private static void AddRelationFilter(ShuffleBlocks blocks, XmlNode xRelation, XmlNode xEntity, ILoggable log) { if (blocks != null && blocks.Count > 0) { var block = CintXML.GetAttribute(xRelation, "Block"); var attribute = CintXML.GetAttribute(xRelation, "Attribute"); var pkattribute = CintXML.GetAttribute(xRelation, "PK-Attribute"); var includenull = CintXML.GetBoolAttribute(xRelation, "IncludeNull", false); List <string> ids = new List <string>(); CintDynEntityCollection parentcoll = blocks.ContainsKey(block) ? blocks[block] : null; if (parentcoll != null && parentcoll.Count > 0) { foreach (CintDynEntity parent in parentcoll) { if (string.IsNullOrEmpty(pkattribute)) { ids.Add(parent.Id.ToString()); } else { ids.Add(parent.Property <EntityReference>(pkattribute, new EntityReference()).Id.ToString()); } } } else { // Adding temp guid to indicate "no matches", as ConditionOperator.In will fail if no values are given ids.Add(new Guid().ToString()); } if (!includenull) { CintFetchXML.AppendFilter(xEntity, "and", attribute, "in", ids.ToArray()); } else { var xFilter = CintFetchXML.AppendFilter(xEntity, "or"); CintFetchXML.AppendCondition(xFilter, attribute, "null"); CintFetchXML.AppendCondition(xFilter, attribute, "in", ids.ToArray()); } log.Log("Adding relation condition for {0} in {1} values in {2}.{3}", attribute, ids.Count, block, pkattribute); } }
private bool DoImportSolution(XmlNode xImport, string filename, Version version) { log.StartSection(MethodBase.GetCurrentMethod().Name); var result = false; bool activatecode = CintXML.GetBoolAttribute(xImport, "ActivateServersideCode", false); bool overwrite = CintXML.GetBoolAttribute(xImport, "OverwriteCustomizations", false); Exception ex = null; SendLine("Importing solution: {0} Version: {1}", filename, version); byte[] fileBytes = File.ReadAllBytes(filename); ImportSolutionRequest impSolReq = new ImportSolutionRequest() { CustomizationFile = fileBytes, OverwriteUnmanagedCustomizations = overwrite, PublishWorkflows = activatecode, ImportJobId = Guid.NewGuid() }; if (crmsvc is CrmServiceProxy && ((CrmServiceProxy)crmsvc).CrmVersion.Major >= 6) { // CRM 2013 or later, import async result = DoImportSolutionAsync(impSolReq, ref ex); } else { // Pre CRM 2013, import sync result = DoImportSolutionSync(impSolReq, ref ex); } if (!result && stoponerror) { if (ex != null) { throw ex; } else { throw new Exception("Solution import failed"); } } log.Log("Returning: {0}", result); log.EndSection(); return(result); }
private SolutionImportConditions CheckIfImportRequired(XmlNode xImport, string name, Version thisversion) { log.StartSection("CheckIfImportRequired"); SolutionImportConditions result = SolutionImportConditions.Create; bool overwritesame = CintXML.GetBoolAttribute(xImport, "OverwriteSameVersion", true); bool overwritenewer = CintXML.GetBoolAttribute(xImport, "OverwriteNewerVersion", false); CintDynEntityCollection cSolutions = GetExistingSolutions(); foreach (CintDynEntity cdSolution in cSolutions) { if (cdSolution.Property("uniquename", "") == name) { // Now we have found the same solution in target environment result = SolutionImportConditions.Update; var existingversion = new Version(cdSolution.Property("version", "1.0.0.0")); log.Log("Existing solution has version: {0}", existingversion); var comparison = thisversion.CompareTo(existingversion); if (!overwritesame && comparison == 0) { result = SolutionImportConditions.Skip; SendLine("Solution {0} {1} already exists in target", name, thisversion); } else if (!overwritenewer && comparison < 0) { result = SolutionImportConditions.Skip; SendLine("Existing solution {0} {1} is newer than {2}", name, existingversion, thisversion); } else if (existingversion == thisversion) { SendLine("Updating version {0}", thisversion); } else { SendLine("Replacing version {0} with {1}", existingversion, thisversion); } break; } } log.Log("Import Condition: {0}", result); log.EndSection(); return(result); }
/// <summary> /// Import entities to CRM from dictionary of blocks /// </summary> /// <param name="blocks">Blocks with entities to import</param> /// <returns>Tuple with counters for: Created, Updated, Skipped and Failed records</returns> public Tuple <int, int, int, int, int, EntityReferenceCollection> ImportToCRM(ShuffleBlocks blocks) { log.StartSection("ImportToCRM"); if (definition == null) { throw new ArgumentNullException("Definition", "Shuffle definition must be specified to import data"); } int created = 0; int updated = 0; int skipped = 0; int deleted = 0; int failed = 0; EntityReferenceCollection references = new EntityReferenceCollection(); XmlNode xRoot = CintXML.FindChild(definition, "ShuffleDefinition"); XmlNode xBlocks = CintXML.FindChild(xRoot, "Blocks"); if (xBlocks != null) { guidmap = new Dictionary <Guid, Guid>(); stoponerror = CintXML.GetBoolAttribute(xRoot, "StopOnError", false); timeout = CintXML.GetIntAttribute(xRoot, "Timeout", -1); double savedtimeout = -1; if (timeout > -1) { try { SendLine("Setting timeout: {0} minutes", timeout); OrganizationServiceProxy orgsvcpxy = crmsvc.GetService <OrganizationServiceProxy>(); savedtimeout = orgsvcpxy.Timeout.TotalMinutes; orgsvcpxy.Timeout = new TimeSpan(0, timeout, 0); } catch (InvalidPluginExecutionException) { // Couldn't cast to correct service type, for some reason... savedtimeout = -1; } } int totalBlocks = xBlocks.ChildNodes.Count; int currentBlock = 0; foreach (XmlNode xBlock in xBlocks.ChildNodes) { currentBlock++; SendStatus(totalBlocks, currentBlock, -1, -1); if (xBlock.NodeType == XmlNodeType.Element) { switch (xBlock.Name) { case "DataBlock": string name = CintXML.GetAttribute(xBlock, "Name"); if (!blocks.ContainsKey(name)) { blocks.Add(name, new CintDynEntityCollection()); } Tuple <int, int, int, int, int, EntityReferenceCollection> dataresult = ImportDataBlock(xBlock, blocks[name]); created += dataresult.Item1; updated += dataresult.Item2; skipped += dataresult.Item3; deleted += dataresult.Item4; failed += dataresult.Item5; references.AddRange(dataresult.Item6); break; case "SolutionBlock": var solutionresult = ImportSolutionBlock(xBlock); switch (solutionresult) { case ItemImportResult.Created: created++; break; case ItemImportResult.Updated: updated++; break; case ItemImportResult.Skipped: skipped++; break; case ItemImportResult.Failed: failed++; break; } break; } } } SendStatus(0, 0, 0, 0); if (savedtimeout > -1) { OrganizationServiceProxy orgsvcpxy = crmsvc.GetService <OrganizationServiceProxy>(); orgsvcpxy.Timeout = new TimeSpan(0, (int)savedtimeout, 0); } } log.EndSection(); return(new Tuple <int, int, int, int, int, EntityReferenceCollection>(created, updated, skipped, deleted, failed, references)); }
/// <summary> /// Export entities from CRM to dictionary of blocks with entities /// </summary> /// <returns>Blocks with exported entities</returns> public ShuffleBlocks ExportFromCRM() { log.StartSection("ExportFromCRM"); if (definition == null) { throw new ArgumentNullException("Definition", "Shuffle definition must be specified to export data"); } ShuffleBlocks blocks = new ShuffleBlocks(); ExistingSolutionVersions = null; XmlNode xRoot = CintXML.FindChild(definition, "ShuffleDefinition"); XmlNode xBlocks = CintXML.FindChild(xRoot, "Blocks"); if (xBlocks != null) { stoponerror = CintXML.GetBoolAttribute(xRoot, "StopOnError", false); timeout = CintXML.GetIntAttribute(xRoot, "Timeout", -1); double savedtimeout = -1; if (timeout > -1) { SendLine("Setting timeout: {0} minutes", timeout); OrganizationServiceProxy orgsvcpxy = crmsvc.GetService <OrganizationServiceProxy>(); savedtimeout = orgsvcpxy.Timeout.TotalMinutes; orgsvcpxy.Timeout = new TimeSpan(0, timeout, 0); } int totalBlocks = xBlocks.ChildNodes.Count; int currentBlock = 0; foreach (XmlNode xBlock in xBlocks.ChildNodes) { currentBlock++; SendStatus(totalBlocks, currentBlock, -1, -1); if (xBlock.NodeType == XmlNodeType.Element) { switch (xBlock.Name) { case "DataBlock": CintDynEntityCollection cExported = ExportDataBlock(blocks, xBlock); string name = CintXML.GetAttribute(xBlock, "Name"); if (cExported != null) { if (blocks.ContainsKey(name)) { SendLine("Block already added: {0}", name); } else { blocks.Add(name, cExported); } } break; case "SolutionBlock": if (ExistingSolutionVersions == null) { GetCurrentVersions(); } ExportSolutionBlock(xBlock); break; } } } SendStatus(0, 0, 0, 0); if (savedtimeout > -1) { OrganizationServiceProxy orgsvcpxy = crmsvc.GetService <OrganizationServiceProxy>(); orgsvcpxy.Timeout = new TimeSpan(0, (int)savedtimeout, 0); } } log.EndSection(); return(blocks); }
private CintDynEntityCollection ExportDataBlock(ShuffleBlocks blocks, XmlNode xBlock) { log.StartSection("ExportDataBlock"); string name = CintXML.GetAttribute(xBlock, "Name"); log.Log("Block: {0}", name); CintDynEntityCollection cExportEntities = null; if (xBlock.Name != "DataBlock") { throw new ArgumentOutOfRangeException("Type", xBlock.Name, "Invalid Block type"); } string entity = CintXML.GetAttribute(xBlock, "Entity"); string type = CintXML.GetAttribute(xBlock, "Type"); XmlNode xExport = CintXML.FindChild(xBlock, "Export"); if (xExport != null) { if (string.IsNullOrEmpty(entity)) { entity = CintXML.GetAttribute(xExport, "Entity"); } #region Define attributes XmlNode xAttributes = CintXML.FindChild(xExport, "Attributes"); bool allcolumns = false; List <string> lAttributes = new List <string>(); List <string> lNullAttributes = new List <string>(); if (xAttributes != null) { foreach (XmlNode xAttr in xAttributes.ChildNodes) { if (xAttr.Name == "Attribute") { string attr = CintXML.GetAttribute(xAttr, "Name"); log.Log("Adding column: {0}", attr); lAttributes.Add(attr.Replace("*", "%")); if (attr.Contains("*")) { allcolumns = true; log.Log("Found wildcard"); } else { bool includenull = CintXML.GetBoolAttribute(xAttr, "IncludeNull", false); if (includenull) { lNullAttributes.Add(attr); } } } } } else { allcolumns = true; lAttributes.Add("*"); log.Log("Attributes not specified, retrieving all"); } #endregion Define attributes if (type == "Entity" || string.IsNullOrEmpty(type)) { #region QueryExpression Entity log.StartSection("Export entity " + entity); QueryExpression qExport = new QueryExpression(entity); if (CintXML.GetBoolAttribute(xExport, "ActiveOnly", true)) { CintQryExp.AppendConditionActive(qExport.Criteria); } foreach (var xBlockChild in xBlock.ChildNodes.Cast <XmlNode>()) { if (xBlockChild.Name == "Relation") { AddRelationFilter(blocks, xBlockChild, qExport.Criteria, log); } } foreach (XmlNode xExpProp in xExport.ChildNodes) { if (xExport.NodeType == XmlNodeType.Element) { switch (xExpProp.Name) { case "#comment": case "Attributes": break; case "Filter": AddFilter(qExport, xExpProp); break; case "Sort": qExport.AddOrder( CintXML.GetAttribute(xExpProp, "Attribute"), CintXML.GetAttribute(xExpProp, "Type") == "Desc" ? OrderType.Descending : OrderType.Ascending); break; default: throw new ArgumentOutOfRangeException("Name", xExpProp.Name, "Invalid subitem to export block " + name); } } } if (allcolumns) { qExport.ColumnSet = new ColumnSet(true); } else { foreach (string attr in lAttributes) { qExport.ColumnSet.AddColumn(attr); } } #if DEBUG log.Log("Converting to FetchXML"); try { var fetch = CintQryExp.ConvertToFetchXml(qExport, crmsvc); log.Log("Exporting {0}:\n{1}", entity, fetch); } catch (Exception ex) { log.Log("Conversion error:"); log.Log(ex); } #endif cExportEntities = CintDynEntity.RetrieveMultiple(crmsvc, qExport, log); if (allcolumns) { SelectAttributes(cExportEntities, lAttributes, lNullAttributes); } SendLine("Block {0} - {1} records", name, cExportEntities.Count); log.EndSection(); #endregion QueryExpression Entity } else if (type == "Intersect") { #region FetchXML Intersect log.StartSection("Export intersect " + entity); XmlDocument xDoc = new XmlDocument(); XmlNode xEntity = CintFetchXML.Create(xDoc, entity); CintFetchXML.AddAttribute(xEntity, lAttributes.ToArray()); foreach (var xBlockChild in xBlock.ChildNodes.Cast <XmlNode>()) { if (xBlockChild.Name == "Relation") { AddRelationFilter(blocks, xBlockChild, xEntity, log); } } var fetch = xDoc.OuterXml; fetch = fetch.Replace("<fetch ", "<fetch {0} {1} "); // Detta för att se till att CrmServiceProxy.RetrieveMultiple kan hantera paging #if DEBUG log.Log("Exporting intersect entity {0}\n{1}", entity, fetch); #endif var qExport = new FetchExpression(fetch); cExportEntities = CintDynEntity.RetrieveMultiple(crmsvc, qExport, log); foreach (var cde in cExportEntities) { List <KeyValuePair <string, object> > newattributes = new List <KeyValuePair <string, object> >(); foreach (var attr in cde.Attributes) { if (attr.Value is Guid) { var attrname = attr.Key; string relatedentity = attrname.Substring(0, attrname.Length - (attrname.EndsWith("idone") || attrname.EndsWith("idtwo") ? 5 : 2)); newattributes.Add(new KeyValuePair <string, object>(attrname, new EntityReference(relatedentity, (Guid)attr.Value))); } } foreach (var newattr in newattributes) { if (!newattr.Key.Equals(cde.PrimaryIdAttribute)) { cde.AddProperty(newattr.Key, newattr.Value); } } } log.EndSection(); #endregion FetchXML Intersect } log.Log("Returning {0} records", cExportEntities.Count); } log.EndSection(); return(cExportEntities); }
private void AddRelationFilter(ShuffleBlocks blocks, XmlNode xRelation, FilterExpression filter, ILoggable log) { log.StartSection(MethodBase.GetCurrentMethod().Name); if (blocks != null && blocks.Count > 0) { var block = CintXML.GetAttribute(xRelation, "Block"); var attribute = CintXML.GetAttribute(xRelation, "Attribute"); var pkattribute = CintXML.GetAttribute(xRelation, "PK-Attribute"); var includenull = CintXML.GetBoolAttribute(xRelation, "IncludeNull", false); var entityName = xRelation.ParentNode.Attributes["Entity"].Value; var type = GetAttributeType(attribute, entityName); ConditionExpression cond = new ConditionExpression(); cond.AttributeName = attribute; cond.Operator = Microsoft.Xrm.Sdk.Query.ConditionOperator.In; List <object> ids = new List <object>(); CintDynEntityCollection parentcoll = blocks.ContainsKey(block) ? blocks[block] : null; if (parentcoll != null && parentcoll.Count > 0) { foreach (CintDynEntity parent in parentcoll) { if (string.IsNullOrEmpty(pkattribute)) { if (type == AttributeTypeCode.String) { ids.Add(parent.Id.ToString()); } else { ids.Add(parent.Id); } } else if (type == AttributeTypeCode.String) { ids.Add(parent.Property <EntityReference>(pkattribute, new EntityReference()).Id.ToString()); } else { ids.Add(parent.Property <EntityReference>(pkattribute, new EntityReference()).Id); } } } else { // Adding temp guid to indicate "no matches", as ConditionOperator.In will fail if no values are given ids.Add(new Guid()); } cond.Values.AddRange(ids); if (!includenull) { filter.AddCondition(cond); } else { var orfilter = new FilterExpression(LogicalOperator.Or); orfilter.AddCondition(attribute, Microsoft.Xrm.Sdk.Query.ConditionOperator.Null); orfilter.AddCondition(cond); filter.AddFilter(orfilter); } log.Log("Adding relation condition for {0} in {1} values in {2}.{3}", attribute, ids.Count, block, pkattribute); } log.EndSection(); }
private void ExportSolutionBlock(XmlNode xBlock) { log.StartSection("ExportSolutionBlock"); if (xBlock.Name != "SolutionBlock") { throw new ArgumentOutOfRangeException("Type", xBlock.Name, "Invalid Block type"); } string name = CintXML.GetAttribute(xBlock, "Name"); log.Log("Block: {0}", name); string path = CintXML.GetAttribute(xBlock, "Path"); string file = CintXML.GetAttribute(xBlock, "File"); if (string.IsNullOrWhiteSpace(path) && !string.IsNullOrWhiteSpace(definitionpath)) { path = definitionpath; path += path.EndsWith("\\") ? "" : "\\"; } if (string.IsNullOrWhiteSpace(file)) { file = name; } XmlNode xExport = CintXML.FindChild(xBlock, "Export"); if (xExport != null) { string type = CintXML.GetAttribute(xExport, "Type"); string setversion = CintXML.GetAttribute(xExport, "SetVersion"); bool publish = CintXML.GetBoolAttribute(xExport, "PublishBeforeExport", false); string targetversion = CintXML.GetAttribute(xExport, "TargetVersion"); CintDynEntity cdSolution = GetAndVerifySolutionForExport(name); var currentversion = new Version(cdSolution.Property("version", "1.0.0.0")); SendLine("Solution: {0} {1}", name, currentversion); if (!string.IsNullOrWhiteSpace(setversion)) { SetNewSolutionVersion(setversion, cdSolution, currentversion); } if (publish) { SendLine("Publishing customizations"); crmsvc.Execute(new PublishAllXmlRequest()); } ExportSolutionRequest req = new ExportSolutionRequest() { SolutionName = name }; #if Crm8 if (!string.IsNullOrWhiteSpace(targetversion)) { req.TargetVersion = targetversion; } #endif XmlNode xSettings = CintXML.FindChild(xExport, "Settings"); if (xSettings != null) { req.ExportAutoNumberingSettings = CintXML.GetBoolAttribute(xSettings, "AutoNumbering", false); req.ExportCalendarSettings = CintXML.GetBoolAttribute(xSettings, "Calendar", false); req.ExportCustomizationSettings = CintXML.GetBoolAttribute(xSettings, "Customization", false); req.ExportEmailTrackingSettings = CintXML.GetBoolAttribute(xSettings, "EmailTracking", false); req.ExportGeneralSettings = CintXML.GetBoolAttribute(xSettings, "General", false); req.ExportMarketingSettings = CintXML.GetBoolAttribute(xSettings, "Marketing", false); req.ExportOutlookSynchronizationSettings = CintXML.GetBoolAttribute(xSettings, "OutlookSync", false); req.ExportRelationshipRoles = CintXML.GetBoolAttribute(xSettings, "RelationshipRoles", false); req.ExportIsvConfig = CintXML.GetBoolAttribute(xSettings, "IsvConfig", false); } if (type == "Managed" || type == "Both") { string filename = path + file + "_managed.zip"; SendLine("Exporting solution to: {0}", filename); req.Managed = true; ExportSolutionResponse exportSolutionResponse = (ExportSolutionResponse)crmsvc.Execute(req); byte[] exportXml = exportSolutionResponse.ExportSolutionFile; File.WriteAllBytes(filename, exportXml); } if (type == "Unmanaged" || type == "Both") { string filename = path + file + ".zip"; SendLine("Exporting solution to: {0}", filename); req.Managed = false; ExportSolutionResponse exportSolutionResponse = (ExportSolutionResponse)crmsvc.Execute(req); byte[] exportXml = exportSolutionResponse.ExportSolutionFile; File.WriteAllBytes(filename, exportXml); } } log.EndSection(); }
private Tuple <int, int, int, int, int, EntityReferenceCollection> ImportDataBlock(XmlNode xBlock, CintDynEntityCollection cEntities) { log.StartSection("ImportDataBlock"); int created = 0; int updated = 0; int skipped = 0; int deleted = 0; int failed = 0; EntityReferenceCollection references = new EntityReferenceCollection(); string name = CintXML.GetAttribute(xBlock, "Name"); log.Log("Block: {0}", name); SendStatus(name, null); SendLine(); switch (xBlock.Name) { case "DataBlock": string type = CintXML.GetAttribute(xBlock, "Type"); XmlNode xImport = CintXML.FindChild(xBlock, "Import"); if (xImport != null) { var includeid = CintXML.GetBoolAttribute(xImport, "CreateWithId", false); var save = CintXML.GetAttribute(xImport, "Save"); var delete = CintXML.GetAttribute(xImport, "Delete"); var updateinactive = CintXML.GetBoolAttribute(xImport, "UpdateInactive", false); var updateidentical = CintXML.GetBoolAttribute(xImport, "UpdateIdentical", false); var deprecatedoverwrite = CintXML.GetAttribute(xImport, "Overwrite"); if (!string.IsNullOrWhiteSpace(deprecatedoverwrite)) { SendLine("DEPRECATED use of attribute Overwrite!"); bool overwrite = CintXML.GetBoolAttribute(xImport, "Overwrite", true); save = overwrite ? "CreateUpdate" : "CreateOnly"; } if (string.IsNullOrWhiteSpace(save)) { // Default save = "CreateUpdate"; } if (string.IsNullOrWhiteSpace(delete)) { // Default delete = "None"; } XmlNode xMatch = CintXML.FindChild(xImport, "Match"); var matchattributes = GetMatchAttributes(xMatch); var updateattributes = !updateidentical?GetUpdateAttributes(cEntities) : new List <string>(); var preretrieveall = xMatch != null?CintXML.GetBoolAttribute(xMatch, "PreRetrieveAll", false) : false; SendLine(); SendLine("Importing block {0} - {1} records ", name, cEntities.Count); var i = 1; if (delete == "All" && (matchattributes.Count == 0)) { // All records shall be deleted, no match attribute defined, so just get all and delete all string entity = CintXML.GetAttribute(xBlock, "Entity"); var qDelete = new QueryExpression(entity); qDelete.ColumnSet.AddColumn(crmsvc.PrimaryAttribute(entity, log)); var deleterecords = CintDynEntity.RetrieveMultiple(crmsvc, qDelete, log); SendLine("Deleting ALL {0} - {1} records", entity, deleterecords.Count); foreach (var record in deleterecords) { SendLine("{0:000} Deleting existing: {1}", i, record); try { record.Delete(); deleted++; } catch (FaultException <OrganizationServiceFault> ex) { if (ex.Message.ToUpperInvariant().Contains("DOES NOT EXIST")) { // This may happen through delayed cascade delete in CRM SendLine(" ...already deleted"); } else { throw; } } i++; } } int totalRecords = cEntities.Count; i = 1; CintDynEntityCollection cAllRecordsToMatch = null; foreach (CintDynEntity cdEntity in cEntities) { string unique = cdEntity.Id.ToString(); SendStatus(-1, -1, totalRecords, i); try { Guid oldid = cdEntity.Id; Guid newid = Guid.Empty; ReplaceGuids(cdEntity, includeid); ReplaceUpdateInfo(cdEntity); unique = GetEntityDisplayString(xMatch, cdEntity); SendStatus(null, unique); if (type == "Entity" || string.IsNullOrEmpty(type)) { #region Entity if (matchattributes.Count == 0) { if (save == "Never" || save == "UpdateOnly") { skipped++; SendLine("{0:000} Not saving: {1}", i, unique); } else { if (!includeid) { cdEntity.Id = Guid.Empty; } if (SaveEntity(cdEntity, null, updateinactive, updateidentical, i, unique)) { created++; newid = cdEntity.Id; references.Add(cdEntity.Entity.ToEntityReference()); } } } else { var matches = GetMatchingRecords(cdEntity, matchattributes, updateattributes, preretrieveall, ref cAllRecordsToMatch); if (delete == "All" || (matches.Count == 1 && delete == "Existing")) { foreach (CintDynEntity cdMatch in matches) { SendLine("{0:000} Deleting existing: {1}", i, unique); try { cdMatch.Delete(); deleted++; } catch (FaultException <OrganizationServiceFault> ex) { if (ex.Message.ToUpperInvariant().Contains("DOES NOT EXIST")) { // This may happen through cascade delete in CRM SendLine(" ...already deleted"); } else { throw; } } } matches.Clear(); } if (matches.Count == 0) { if (save == "Never" || save == "UpdateOnly") { skipped++; SendLine("{0:000} Not creating: {1}", i, unique); } else { if (!includeid) { cdEntity.Id = Guid.Empty; } if (SaveEntity(cdEntity, null, updateinactive, updateidentical, i, unique)) { created++; newid = cdEntity.Id; references.Add(cdEntity.Entity.ToEntityReference()); } } } else if (matches.Count == 1) { var match = matches[0]; newid = match.Id; if (save == "CreateUpdate" || save == "UpdateOnly") { if (SaveEntity(cdEntity, match, updateinactive, updateidentical, i, unique)) { updated++; references.Add(cdEntity.Entity.ToEntityReference()); } else { skipped++; } } else { skipped++; SendLine("{0:000} Exists: {1}", i, unique); } } else { failed++; SendLine("Import object matches {0} records in target database!", matches.Count); SendLine(unique); } } if (!oldid.Equals(Guid.Empty) && !newid.Equals(Guid.Empty) && !oldid.Equals(newid) && !guidmap.ContainsKey(oldid)) { log.Log("Mapping IDs: {0} ==> {1}", oldid, newid); guidmap.Add(oldid, newid); } #endregion Entity } else if (type == "Intersect") { #region Intersect if (cdEntity.Attributes.Count != 2) { throw new ArgumentOutOfRangeException("Attributes", cdEntity.Attributes.Count, "Invalid Attribute count for intersect object"); } string intersect = CintXML.GetAttribute(xBlock, "IntersectName"); if (string.IsNullOrEmpty(intersect)) { intersect = cdEntity.Name; } EntityReference ref1 = (EntityReference)cdEntity.Attributes.ElementAt(0).Value; EntityReference ref2 = (EntityReference)cdEntity.Attributes.ElementAt(1).Value; CintDynEntity party1 = CintDynEntity.InitFromNameAndId(ref1.LogicalName, ref1.Id, crmsvc, log); CintDynEntity party2 = CintDynEntity.InitFromNameAndId(ref2.LogicalName, ref2.Id, crmsvc, log); try { party1.Associate(party2, intersect); created++; SendLine("{0} Associated: {1}", i.ToString().PadLeft(3, '0'), name); } catch (Exception ex) { if (ex.Message.Contains("duplicate")) { SendLine("{0} Association exists: {1}", i.ToString().PadLeft(3, '0'), name); skipped++; } else { throw; } } #endregion Intersect } } catch (Exception ex) { failed++; SendLine("\n*** Error record: {0} ***\n{1}", unique, ex.Message); log.Log(ex); if (stoponerror) { throw; } } i++; } SendLine("Created: {0} Updated: {1} Skipped: {2} Deleted: {3} Failed: {4}", created, updated, skipped, deleted, failed); } break; default: throw new ArgumentOutOfRangeException("Type", xBlock.Name, "Invalid Block type"); } log.EndSection(); return(new Tuple <int, int, int, int, int, EntityReferenceCollection>(created, updated, skipped, deleted, failed, references)); }
private ItemImportResult ImportSolutionBlock(XmlNode xBlock) { log.StartSection("ImportSolutionBlock"); var importResult = ItemImportResult.None; if (xBlock.Name != "SolutionBlock") { throw new ArgumentOutOfRangeException("Type", xBlock.Name, "Invalid Block type"); } XmlNode xImport = CintXML.FindChild(xBlock, "Import"); if (xImport != null) { string name = CintXML.GetAttribute(xBlock, "Name"); log.Log("Block: {0}", name); SendStatus(name, null); string type = CintXML.GetAttribute(xImport, "Type"); SendLine(); SendLine("Importing solution: {0}", name); string filename = GetSolutionFilename(xBlock, name, type); var version = ExtractVersionFromSolutionZip(filename); try { ValidatePreReqs(xImport, version); SolutionImportConditions ImportCondition = CheckIfImportRequired(xImport, name, version); if (ImportCondition != SolutionImportConditions.Skip) { if (DoImportSolution(xImport, filename, version)) { if (ImportCondition == SolutionImportConditions.Create) { importResult = ItemImportResult.Created; } else { importResult = ItemImportResult.Updated; } } else { importResult = ItemImportResult.Failed; log.Log("Failed during import"); } bool publish = CintXML.GetBoolAttribute(xImport, "PublishAll", false); if (publish) { SendLine("Publishing customizations"); crmsvc.Execute(new PublishAllXmlRequest()); } } else { importResult = ItemImportResult.Skipped; log.Log("Skipped due to import condition"); } } catch (Exception ex) { log.Log(ex); importResult = ItemImportResult.Failed; if (stoponerror) { throw; } } } log.EndSection(); return(importResult); }