Anyway, the fact of the matter is that we have built up a rather large collection of calendars and calendar rules (90K & 550K last time I checked) and this is slowing our users down. Some operations are slightly slower, to the point that they have not noticed, whereas others are simply painstakingly slow (A custom screen can take up to 1 minute to load), so I (re)used a very simple method to delete a calendar:
1 [WebMethod] 2 public bool Delete(string strEntityName, string strEntityGuid) 3 { 4 try 5 { 6 CreateLog("Trace", "Delete:: Delete( string strEntityName, string strEntityGuid)", 7 "1. IN. strEntityName: " + strEntityName + 8 " - strEntityGuid: " + strEntityGuid + " ."); 9 10 // Set up the CRM Service. 11 //CrmService lCrmService = new CrmService(); 12 //lCrmService.Credentials = System.Net.CredentialCache.DefaultCredentials; 13 //lCrmService.Url = ConfigurationSettings.AppSettings["CRMServiceURL"]; 14 15 Guid objEntityId = new Guid(strEntityGuid); 16 17 CreateLog("Trace", "Delete:: Delete( string strEntityName, string strEntityGuid)", "2. About to Call Delete."); 18 19 lCrmService.Delete(strEntityName, objEntityId); 20 21 CreateLog("Trace", "Delete :: Delete( string strEntityName, string strEntityGuid)", "3. Delete Complete. Returning True"); 22 CreateLog("Audit", "Delete :: Delete( string strEntityName, string strEntityGuid)", "Deleted Call with ID: " + strEntityGuid + " ."); 23 24 return true; 25 } 26 catch (Exception ex) 27 { 28 CreateLog("Error", "Delete :: Delete( string strEntityName, string strEntityGuid)", "Error: " + ex.ToString() + " ."); 29 return false; 30 } 31 }
but alas I got the following error message, when I passed in a calendar:
Crm Exception: Message: The object you tried to delete is associated with another object and cannot be deleted., ErrorCode: -2147220953Fair enough, I thought, I need to delete the calendarrules first, unfortunately I got this error message:
Crm Exception: Message: The 'Delete' method does not support entities of type 'calendarrule'., ErrorCode: -2147219456No dice. The irritating part is that we can delete the calendars directly with a sql statement, a rather convoluted sql statement actually, but this is:
- unsupported
- would require a lot of testing
probablydefinitely a bad idea
Source Code:
1 /// <summary> 2 /// Delete passed in Calendar 3 /// </summary> 4 /// <param name="strEntityGuid">Calendar id</param> 5 /// <returns>true if successful</returns> 6 [WebMethod] 7 public bool TDelete(string strEntityGuid) 8 { 9 try 10 { 11 CreateLog("Trace", "DeleteEntity :: TDelete( string strEntityName, string strEntityGuid)", 12 "1. IN. strEntityGuid: " + strEntityGuid + " ."); 13 14 15 calendar acal = DeleteCalendarRules(strEntityGuid); 16 17 if (acal != null) 18 { 19 //Now, we need to find the main calendar for the equipment this calendar (i.e. strEntityGuid) belongs to 20 //and from that calendar we need to find the calendarrule that we need to delete 21 22 //grab the equipmentid from the name of the calendar so that we can get the equipment this calendar belongs to, remember 23 //that calendars are named as equipmentid + date 24 string equipmentid = System.Text.RegularExpressions.Regex.Match(acal.name.ToUpper(), @"[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}").Value; 25 26 //grab the equipment to which calendar strEntityGuid "belongs" 27 equipment myequip = (equipment)lCrmService.Retrieve(EntityName.equipment.ToString(), new Guid(equipmentid), new AllColumns()); 28 29 //grab the calendar for the above equipment. This is because there is a calendarrule reference to this calendar from strEntityGuid 30 calendar equipmentcal = (calendar)lCrmService.Retrieve(EntityName.calendar.ToString(), myequip.calendarid.Value, new AllColumns()); 31 32 //grab the aforementioned calendarrule so that we can set it to null. Note that this should be unique. 33 string fetch = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'><entity name='calendarrule'><attribute name='calendarruleid'/><filter type='and'><condition attribute='calendarid' operator='eq' value='" + 34 myequip.calendarid.Value.ToString() + "'/><condition attribute='innercalendarid' operator='eq' value='" + strEntityGuid + "'/></filter></entity></fetch>"; 35 36 string result = lCrmService.Fetch(fetch); 37 38 XmlDocument doc = new XmlDocument(); 39 doc.LoadXml(result); 40 string guid = doc.SelectSingleNode("//result").FirstChild.InnerText; 41 42 //loop through all calendar rules for the equipment's calendar 43 //and "drop", i.e. set to null, when it matches the result of the fetch query. 44 //We update the calendar so that the calendarrule is "dropped", this is handled on the background by the platform. 45 for (int i = 0; i < equipmentcal.calendarrules.Length; i++) 46 { 47 calendarrule mycalrul = equipmentcal.calendarrules[i]; 48 49 if (mycalrul.calendarruleid.Value == new Guid(guid)) 50 { 51 equipmentcal.calendarrules[i] = null; 52 lCrmService.Update(equipmentcal); 53 } 54 } 55 56 57 TargetDeleteCalendar target = new TargetDeleteCalendar(); 58 target.EntityId = new Guid(strEntityGuid); 59 60 61 DeleteRequest delete = new DeleteRequest(); 62 delete.Target = target; 63 64 CreateLog("Trace", "DeleteEntity :: TDelete( string strEntityName, string strEntityGuid)", "2. About to Call Delete."); 65 66 //Delete the bad mother 67 DeleteResponse deleted = (DeleteResponse)lCrmService.Execute(delete); 68 69 CreateLog("Trace", "DeleteEntity :: TDelete( string strEntityName, string strEntityGuid)", "3. Delete Complete. Returning True"); 70 CreateLog("Audit", "DeleteEntity :: TDelete( string strEntityName, string strEntityGuid)", "Deleted Callaback with ID: " + strEntityGuid + " ."); 71 72 return true; 73 } 74 else 75 { 76 return false; 77 } 78 } 79 catch (Exception e) 80 { 81 CreateLog("Error", "DeleteEntity :: TDelete( string strEntityName, string strEntityGuid)", "Error: " + e.ToString() + " - source: " + e.Source + " ."); 82 return false; 83 } 84 } 85 86 /// <summary> 87 /// This doesn't actually delete the calendarrules associated with the passed in calendar. 88 /// It simply sets its deletionstatecode to 2, so that the deletion service deletes it 89 /// </summary> 90 /// <param name="strEntityGuid">Calendar id</param> 91 /// <returns>calendar entity</returns> 92 private calendar DeleteCalendarRules(string strEntityGuid) 93 { 94 try 95 { 96 calendar calTBDeleted = (calendar)lCrmService.Retrieve(EntityName.calendar.ToString(), new Guid(strEntityGuid), new AllColumns()); 97 98 //this sets the calendar rules to null. I love this comment :) 99 calTBDeleted.calendarrules = null; 100 101 lCrmService.Update(calTBDeleted); 102 103 return calTBDeleted; 104 } 105 catch (Exception e) 106 { 107 //TODO: log the exception don't be lazy 108 return null; 109 110 } 111 }
No comments:
Post a Comment