コード例 #1
0
ファイル: Common.cs プロジェクト: shytikov/Xrm.Utils
        /// <summary>
        /// Converts QueryExpression to FetchXml
        /// </summary>
        /// <param name="container"></param>
        /// <param name="query"></param>
        /// <returns></returns>
        public static string Convert(this IExecutionContainer container, QueryExpression query)
        {
            container.StartSection($@"{MethodBase.GetCurrentMethod().DeclaringType.Name}\{MethodBase.GetCurrentMethod().Name}");

            try
            {
                var request = new QueryExpressionToFetchXmlRequest()
                {
                    Query = query
                };

                var response = (QueryExpressionToFetchXmlResponse)container?.Service?.Execute(request);

                if (response != null)
                {
                    container.Log("Query was converted successfully.");
                }
                else
                {
                    container.Log("It was an issue converting query.");
                }

                return(response?.FetchXml);
            }
            finally
            {
                container.EndSection();
            }
        }
コード例 #2
0
ファイル: Common.cs プロジェクト: shytikov/Xrm.Utils
        /// <summary>Reloads encapsulated Entity from database</summary>
        /// <param name="container"></param>
        /// <param name="entity"></param>
        /// <param name="columns">Set of colums with which entity should be reloaded</param>
        /// <remarks>ToStringWithEntityName() is replaced with entity.LogicalName</remarks>
        public static Entity Reload(this IExecutionContainer container, Entity entity, ColumnSet columns)
        {
            container.StartSection($@"{MethodBase.GetCurrentMethod().DeclaringType.Name}\{MethodBase.GetCurrentMethod().Name}");

            container.StartSection($"Reloading {container.Entity(entity).ToString()}.");

            foreach (var attr in entity.Attributes.Keys)
            {
                if (attr.Contains('.'))
                {
                    throw new InvalidPluginExecutionException($"Cannot reload entity {entity.LogicalName} with aliased attributes ({attr})");
                }
            }

            if (columns == null)
            {
                columns = new ColumnSet();
            }

            if (!columns.Columns.Any() && !columns.AllColumns)
            {
                foreach (var attr in entity.Attributes.Keys)
                {
                    columns.AddColumn(attr);
                }
            }

            entity = container.Retrieve(entity.ToEntityReference(), columns);
            container.EndSection();

            return(entity);
        }
コード例 #3
0
        /// <summary>
        /// Export entities from CRM to dictionary of blocks with entities
        /// </summary>
        /// <returns>Blocks with exported entities</returns>
        public ShuffleBlocks ExportFromCRM(IExecutionContainer container)
        {
            container.StartSection("ExportFromCRM");
            if (definition == null)
            {
                throw new ArgumentNullException("Definition", "Shuffle definition must be specified to export data");
            }
            var blocks = new ShuffleBlocks();

            ExistingSolutionVersions = null;
            if (ShuffleDefinition.Blocks.Items.Any(b => (b is DataBlock data && data.Export != null) || b is SolutionBlock sol && sol.Export != null))
            {
                stoponerror = ShuffleDefinition.StopOnError;
                timeout     = ShuffleDefinition.TimeoutSpecified ? ShuffleDefinition.Timeout : -1;
                //double savedtimeout = -1;
                //if (timeout > -1)
                //{
                //    savedtimeout = SetTimeout();
                //}

                var totalBlocks  = ShuffleDefinition.Blocks.Items.Length;
                var currentBlock = 0;
                foreach (var block in ShuffleDefinition.Blocks.Items)
                {
                    currentBlock++;
                    SendStatus(totalBlocks, currentBlock, -1, -1);
                    if (block is DataBlock datablock)
                    {
                        var cExported = ExportDataBlock(container, blocks, datablock);
                        var name      = datablock.Name;
                        if (cExported != null)
                        {
                            if (blocks.ContainsKey(name))
                            {
                                SendLine(container, $"Block already added: {name}");
                            }
                            else
                            {
                                blocks.Add(name, cExported);
                            }
                        }
                    }
                    else if (block is SolutionBlock solutionblock)
                    {
                        if (ExistingSolutionVersions == null)
                        {
                            GetCurrentVersions(container);
                        }
                        ExportSolutionBlock(container, solutionblock);
                    }
                }
                SendStatus(0, 0, 0, 0);
                //if (savedtimeout > -1)
                //{
                //    ResetTimeout(container, savedtimeout);
                //}
            }
            container.EndSection();
            return(blocks);
        }
コード例 #4
0
        /// <summary>Returns a list of file names that are required for the given ShuffleDefinition</summary>
        /// <param name="container"></param>
        /// <param name="shuffleDefinition">ShuffleDefinition file</param>
        /// <param name="definitionpath"></param>
        /// <returns>List of files</returns>
        public static List <string> GetReferencedFiles(IExecutionContainer container, string shuffleDefinition, string definitionpath)
        {
            container.StartSection(MethodBase.GetCurrentMethod().Name);
            var result = new List <string>();

            if (File.Exists(shuffleDefinition))
            {
                var definition = GetShuffleDefinition(shuffleDefinition, true);
                if (DataFileRequired(definition))
                {
                    var datafile = Path.ChangeExtension(shuffleDefinition, ".data.xml");
                    container.Log($"Adding data file: {datafile}");
                    result.Add(datafile);
                }
                foreach (var solBlock in definition.Blocks.Items.Where(b => b is SolutionBlock))
                {
                    var solFile = GetSolutionFilename((SolutionBlock)solBlock, definitionpath);
                    if (!result.Contains(solFile))
                    {
                        container.Log($"Adding solution file: {solFile}");
                        result.Add(solFile);
                    }
                }
            }
            else
            {
                container.Log("Definition file not found");
            }
            container.Log($"Returning {result.Count} files");
            container.EndSection();
            return(result);
        }
コード例 #5
0
        /// <summary>
        /// Serialize blocks with entities with given serialization type
        /// </summary>
        /// <param name="container"></param>
        /// <param name="blocks"></param>
        /// <param name="type"></param>
        /// <param name="delimeter">Optional, only required for SerializationType: Text</param>
        /// <returns></returns>
        public XmlDocument Serialize(IExecutionContainer container, ShuffleBlocks blocks, SerializationType type, char delimeter)
        {
            container.StartSection("Serialize");
            XmlDocument xml = null;

            if (blocks.Count > 0)
            {
                SendLine(container, "Serializing {0} blocks with type {1}", blocks.Count, type);
                xml = new XmlDocument();
                XmlNode root = xml.CreateElement("ShuffleData");
                xml.AppendChild(root);
                XML.AppendAttribute(root, "Type", type.ToString());
                XML.AppendAttribute(root, "ExportTime", DateTime.Now.ToString("s"));
                switch (type)
                {
                case SerializationType.Full:
                case SerializationType.Simple:
                case SerializationType.SimpleWithValue:
                case SerializationType.SimpleNoId:
                case SerializationType.Explicit:
                    foreach (var block in blocks.Keys)
                    {
                        SendLine(container, $"Serializing {blocks[block].Count()} records in block {block}");
                        XmlNode xBlock = xml.CreateElement("Block");
                        root.AppendChild(xBlock);
                        XML.AppendAttribute(xBlock, "Name", block);
                        XML.AppendAttribute(xBlock, "Count", blocks[block].Count().ToString());

                        var xSerialized = blocks[block].Serialize(container, (SerializationStyle)type);
                        xBlock.AppendChild(xml.ImportNode(xSerialized.ChildNodes[0], true));
                    }
                    break;

                case SerializationType.Text:
                    XML.AppendAttribute(root, "Delimeter", delimeter.ToString());
                    var text = new StringBuilder();
                    foreach (var block in blocks.Keys)
                    {
                        SendLine(container, $"Serializing {blocks[block].Count()} records in block {block}");
                        text.AppendLine("<<<" + block + ">>>");
                        var serializedblock = blocks[block].ToTextFile(container, delimeter);
                        text.Append(serializedblock);
                    }
                    XML.AddCDATANode(root, "Text", text.ToString());
                    break;
                }
            }
            container.EndSection();
            return(xml);
        }
コード例 #6
0
        private EntityCollection GetAllRecordsForMatching(IExecutionContainer container, List <string> allattributes, Entity cdEntity)
        {
            container.StartSection(MethodBase.GetCurrentMethod().Name);
            var qMatch = new QueryExpression(cdEntity.LogicalName)
            {
                ColumnSet = new ColumnSet(allattributes.ToArray())
            };

#if DEBUG
            container.Log($"Retrieving all records for {cdEntity.LogicalName}:\n{container.ConvertToFetchXml(qMatch)}");
#endif
            var matches = container.RetrieveMultiple(qMatch);
            SendLine(container, $"Pre-retrieved {matches.Count()} records for matching");
            container.EndSection();
            return(matches);
        }
コード例 #7
0
        private EntityCollection GetMatchingRecordsFromPreRetrieved(IExecutionContainer container, List <string> matchattributes, Entity cdEntity, EntityCollection cAllRecordsToMatch)
        {
            container.StartSection(MethodBase.GetCurrentMethod().Name);
            container.Log($"Searching matches for: {cdEntity.Id} {cdEntity.LogicalName}");
            var result = new EntityCollection();

            foreach (var cdRecord in cAllRecordsToMatch.Entities)
            {
                if (EntityAttributesEqual(container, matchattributes, cdEntity, cdRecord))
                {
                    result.Add(cdRecord);
                    container.Log($"Found match: {cdRecord.Id} {cdRecord.LogicalName}");
                }
            }
            container.Log($"Returned matches: {result.Count()}");
            container.EndSection();
            return(result);
        }
コード例 #8
0
        /// <summary>Import data in Data according to shuffle definition in Definition</summary>
        /// <param name="container"></param>
        /// <param name="Definition">Shuffle Definition</param>
        /// <param name="Data">Exported data</param>
        /// <param name="ShuffleEventHandler">Event handler processing messages from the import. May be null.</param>
        /// <param name="defpath">Path to definition file, if not standard</param>
        /// <param name="clearRemainingShuffleVars"></param>
        /// <returns>Tuple with counters for: Created, Updated, Skipped and Failed records and a collection of entityreferences for the created/updated records</returns>
        public static Tuple <int, int, int, int, int, EntityReferenceCollection> QuickImport(IExecutionContainer container, XmlDocument Definition, XmlDocument Data, EventHandler <ShuffleEventArgs> ShuffleEventHandler, string defpath, bool clearRemainingShuffleVars)
        {
            container.StartSection("QuickImport");
            var shuffle = new Shuffler(container);

            if (ShuffleEventHandler != null)
            {
                shuffle.RaiseShuffleEvent += ShuffleEventHandler;
            }
            ShuffleHelper.VerifyShuffleVars(Definition, clearRemainingShuffleVars);
            shuffle.Definition     = Definition;
            shuffle.definitionpath = defpath;
            var blocks = shuffle.Deserialize(container, Data);
            var result = shuffle.ImportToCRM(container, blocks);

            container.EndSection();
            return(result);
        }
コード例 #9
0
        /// <summary>Export data according to shuffle definition in Definition to format Type</summary>
        /// <param name="container"></param>
        /// <param name="Definition">Shuffle Definition</param>
        /// <param name="Type">Type of target file</param>
        /// <param name="Delimeter">Delimeter to use when exporting to Type: Text</param>
        /// <param name="ShuffleEventHandler">Event handler processing messages from the export. May be null.</param>
        /// <param name="defpath">Folder path for the shuffle definition file.</param>
        /// <param name="clearRemainingShuffleVars"></param>
        /// <returns>XmlDocument with exported data</returns>
        public static XmlDocument QuickExport(IExecutionContainer container, XmlDocument Definition, SerializationType Type, char Delimeter, EventHandler <ShuffleEventArgs> ShuffleEventHandler, string defpath, bool clearRemainingShuffleVars)
        {
            container.StartSection("QuickExport");
            var shuffle = new Shuffler(container);

            if (ShuffleEventHandler != null)
            {
                shuffle.RaiseShuffleEvent += ShuffleEventHandler;
            }
            ShuffleHelper.VerifyShuffleVars(Definition, clearRemainingShuffleVars);
            shuffle.Definition     = Definition;
            shuffle.definitionpath = defpath;
            var blocks = shuffle.ExportFromCRM(container);
            var result = shuffle.Serialize(container, blocks, Type, Delimeter);

            container.EndSection();
            return(result);
        }
コード例 #10
0
ファイル: Common.cs プロジェクト: shytikov/Xrm.Utils
        /// <summary>
        /// </summary>
        /// <param name="container"></param>
        /// <param name="entity1"></param>
        /// <param name="entity2"></param>
        /// <returns></returns>
        public static Entity Merge(this IExecutionContainer container, Entity entity1, Entity entity2)
        {
            container.StartSection($@"{MethodBase.GetCurrentMethod().DeclaringType.Name}\{MethodBase.GetCurrentMethod().Name}");

            container.Log($"Merging {entity1.LogicalName} {container.Entity(entity1).ToString()} with {entity2.LogicalName} {container.Entity(entity2).ToString()}");

            var merge = entity1.CloneAttributes();

            foreach (var prop in entity2.Attributes)
            {
                if (!merge.Attributes.Contains(prop.Key))
                {
                    merge.Attributes.Add(prop);
                }
            }

            container.Log($"Base entity had {entity1.Attributes.Count} attributes. Second entity {entity2.Attributes.Count}. Merged entity has {merge.Attributes.Count}");
            container.EndSection();
            return(merge);
        }
コード例 #11
0
        private SolutionImportConditions CheckIfImportRequired(IExecutionContainer container, SolutionBlockImport import, string name, Version thisversion)
        {
            container.StartSection("CheckIfImportRequired");
            var result         = SolutionImportConditions.Create;
            var overwritesame  = import.OverwriteSameVersion;
            var overwritenewer = import.OverwriteNewerVersion;
            var cSolutions     = GetExistingSolutions(container);

            foreach (var cdSolution in cSolutions.Entities)
            {
                if (cdSolution.GetAttribute("uniquename", "") == name)
                {   // Now we have found the same solution in target environment
                    result = SolutionImportConditions.Update;
                    var existingversion = new Version(cdSolution.GetAttribute("version", "1.0.0.0"));
                    container.Log("Existing solution has version: {0}", existingversion);
                    var comparison = thisversion.CompareTo(existingversion);
                    if (!overwritesame && comparison == 0)
                    {
                        result = SolutionImportConditions.Skip;
                        SendLine(container, "Solution {0} {1} already exists in target", name, thisversion);
                    }
                    else if (!overwritenewer && comparison < 0)
                    {
                        result = SolutionImportConditions.Skip;
                        SendLine(container, "Existing solution {0} {1} is newer than {2}", name, existingversion, thisversion);
                    }
                    else if (existingversion == thisversion)
                    {
                        SendLine(container, "Updating version {0}", thisversion);
                    }
                    else
                    {
                        SendLine(container, "Replacing version {0} with {1}", existingversion, thisversion);
                    }
                    break;
                }
            }
            container.Log("Import Condition: {0}", result);
            container.EndSection();
            return(result);
        }
コード例 #12
0
        /// <summary>Get the current versions for all solutions defined in the definition file</summary>
        /// <remarks>Results will be placed in the public dictionary <c ref="ExistingSolutionVersions">ExistingSolutionVersions</c></remarks>
        public void GetCurrentVersions(IExecutionContainer container)
        {
            container.StartSection("GetCurrentVersions");
            ExistingSolutionVersions = new Dictionary <string, Version>();
            var xRoot   = XML.FindChild(definition, "ShuffleDefinition");
            var xBlocks = XML.FindChild(xRoot, "Blocks");

            if (xBlocks != null)
            {
                var solutions = GetExistingSolutions(container);
                foreach (XmlNode xBlock in xBlocks.ChildNodes)
                {
                    if (xBlock.NodeType == XmlNodeType.Element)
                    {
                        switch (xBlock.Name)
                        {
                        case "DataBlock":
                            break;

                        case "SolutionBlock":
                            var xmlNode = XML.FindChild(xBlock, "Export");
                            if (xmlNode != null)
                            {
                                var name = XML.GetAttribute(xBlock, "Name");
                                container.Log("Getting version for: {0}", name);
                                foreach (var solution in solutions.Entities)
                                {
                                    if (name.Equals(solution.GetAttribute("uniquename", ""), StringComparison.OrdinalIgnoreCase))
                                    {
                                        ExistingSolutionVersions.Add(name, new Version(solution.GetAttribute("version", "1.0.0.0")));
                                        container.Log($"Version found: {ExistingSolutionVersions[name]}");
                                    }
                                }
                            }
                            break;
                        }
                    }
                }
            }
            container.EndSection();
        }
コード例 #13
0
        private AttributeTypeCode?GetAttributeType(IExecutionContainer container, string attribute, string entityName)
        {
            container.StartSection(MethodBase.GetCurrentMethod().Name + " " + entityName + "." + attribute);
            AttributeTypeCode?type = null;
            var eqe = new EntityQueryExpression
            {
                Properties = new MetadataPropertiesExpression()
            };

            eqe.Properties.PropertyNames.Add("Attributes");
            eqe.Criteria.Conditions.Add(new MetadataConditionExpression("LogicalName", MetadataConditionOperator.Equals, entityName));
            var aqe = new AttributeQueryExpression
            {
                Properties = new MetadataPropertiesExpression("LogicalName", "AttributeType")
            };

            eqe.AttributeQuery = aqe;
            var req = new RetrieveMetadataChangesRequest()
            {
                Query = eqe,
                ClientVersionStamp = null
            };
            var resp = (RetrieveMetadataChangesResponse)container.Execute(req);

            if (resp.EntityMetadata.Count == 1)
            {
                foreach (var attr in resp.EntityMetadata[0].Attributes)
                {
                    if (attr.LogicalName == attribute)
                    {
                        type = attr.AttributeType;
                        break;
                    }
                }
            }
            container.Log($"Type: {type}");
            container.EndSection();
            return(type);
        }
コード例 #14
0
        /// <summary>
        /// Deserialize xml/string to blocks with entities
        /// </summary>
        /// <param name="container"></param>
        /// <param name="serialized"></param>
        /// <returns>Optional, only required for SerializationType: Text</returns>
        public ShuffleBlocks Deserialize(IExecutionContainer container, XmlDocument serialized)
        {
            container.StartSection("Deserialize");
            var result = new ShuffleBlocks();

            if (serialized != null)
            {
                var root    = XML.FindChild(serialized, "ShuffleData");
                var sertype = XML.GetAttribute(root, "Type");
                SendLine(container, $"Deserialize from {sertype}");
                if (sertype == SerializationType.Full.ToString() ||
                    sertype == SerializationType.Simple.ToString() ||
                    sertype == SerializationType.SimpleNoId.ToString() ||
                    sertype == SerializationType.SimpleWithValue.ToString() ||
                    sertype == SerializationType.Explicit.ToString())
                {
                    foreach (XmlNode xBlock in root.ChildNodes)
                    {
                        if (xBlock.NodeType == XmlNodeType.Element && xBlock.Name == "Block" && xBlock.ChildNodes.Count == 1)
                        {
                            var name = XML.GetAttribute(xBlock, "Name");
                            var xml  = new XmlDocument();
                            xml.AppendChild(xml.ImportNode(xBlock.ChildNodes[0], true));
                            var cEntities = container.CreateEntityCollection(xml);
                            SendLine(container, $"Block {name}: {cEntities.Count()} records");
                            result.Add(name, cEntities);
                        }
                    }
                }
                else if (sertype == SerializationType.Text.ToString())
                {
                    var           strdelimeter    = XML.GetAttribute(root, "Delimeter");
                    var           delimeter       = strdelimeter.Length == 1 ? strdelimeter[0] : '\t';
                    var           xText           = XML.FindChild(root, "Text");
                    var           reader          = new StringReader(xText.InnerText);
                    var           line            = 0;
                    var           name            = "";
                    StringBuilder serializedblock = null;
                    var           current         = reader.ReadLine();
                    while (current != null)
                    {
                        container.Log("Line {0:000}: {1}", line, current);
                        if (current.StartsWith("<<<") && current.Contains(">>>"))
                        {
                            container.Log("Block start");
                            if (!string.IsNullOrWhiteSpace(name) && serializedblock != null)
                            {
                                var cEntities = container.CreateEntityCollection(serializedblock.ToString(), delimeter);
                                result.Add(name, cEntities);
                                SendLine(container, $"Block {name}: {cEntities.Count()} records");
                            }
                            name            = current.Substring(3);
                            name            = name.Substring(0, name.IndexOf(">>>", StringComparison.Ordinal));
                            serializedblock = new StringBuilder();
                        }
                        else
                        {
                            serializedblock.AppendLine(current);
                        }
                        current = reader.ReadLine();
                        line++;
                    }
                    if (!string.IsNullOrWhiteSpace(serializedblock.ToString()))
                    {
                        var cEntities = container.CreateEntityCollection(serializedblock.ToString(), delimeter);
                        result.Add(name, cEntities);
                        SendLine(container, $"Block {name}: {cEntities.Count()} records");
                    }
                }
            }
            container.EndSection();
            return(result);
        }
コード例 #15
0
        private void ValidatePreReqs(IExecutionContainer container, SolutionBlockImport import, Version thisversion)
        {
            if (import.PreRequisites == null)
            {
                container.Log("No prereqs for solution import");
                return;
            }
            container.StartSection("ValidatePreReqs");
            var cSolutions = GetExistingSolutions(container);

            foreach (var prereq in import.PreRequisites)
            {
                var valid    = false;
                var name     = prereq.Name;
                var comparer = prereq.Comparer;
                var version  = new Version();
                container.Log("Prereq: {0} {1} {2}", name, comparer, version);

                if (comparer == SolutionVersionComparers.eqthis || comparer == SolutionVersionComparers.gethis)
                {
                    version  = thisversion;
                    comparer = comparer == SolutionVersionComparers.eqthis ? SolutionVersionComparers.eq : comparer == SolutionVersionComparers.gethis ? SolutionVersionComparers.ge : comparer;
                }
                else if (comparer != SolutionVersionComparers.any)
                {
                    version = new Version(prereq.Version.Replace('*', '0'));
                }

                foreach (var cdSolution in cSolutions.Entities)
                {
                    if (cdSolution.GetAttribute("uniquename", "") == name)
                    {
                        container.Log("Found matching solution");
                        switch (comparer)
                        {
                        case SolutionVersionComparers.any:
                            valid = true;
                            break;

                        case SolutionVersionComparers.eq:
                            valid = new Version(cdSolution.GetAttribute("version", "1.0.0.0")).Equals(version);
                            break;

                        case SolutionVersionComparers.ge:
                            valid = new Version(cdSolution.GetAttribute("version", "<undefined>")) >= version;
                            break;

                        default:
                            throw new ArgumentOutOfRangeException("Comparer", comparer, "Invalid comparer value");
                        }
                    }
                    if (valid)
                    {
                        break;
                    }
                }
                if (valid)
                {
                    SendLine(container, "Prerequisite {0} {1} {2} is satisfied", name, comparer, version);
                }
                else
                {
                    SendLine(container, "Prerequisite {0} {1} {2} is NOT satisfied", name, comparer, version);
                    throw new Exception("Prerequisite NOT satisfied (" + name + " " + comparer + " " + version + ")");
                }
            }
            container.EndSection();
        }
コード例 #16
0
        private void AddRelationFilter(IExecutionContainer container, ShuffleBlocks blocks, string entityName, DataBlockRelation relation, FilterExpression filter)
        {
            container.StartSection(MethodBase.GetCurrentMethod().Name);
            if (blocks != null && blocks.Count > 0)
            {
                var block       = relation.Block;
                var attribute   = relation.Attribute;
                var pkattribute = relation.PKAttribute;
                var includenull = relation.IncludeNull;

                var type = GetAttributeType(container, attribute, entityName);

                var cond = new ConditionExpression
                {
                    AttributeName = attribute,
                    Operator      = Microsoft.Xrm.Sdk.Query.ConditionOperator.In
                };

                var ids        = new List <object>();
                var parentcoll = blocks.ContainsKey(block) ? blocks[block] : null;
                if (parentcoll != null && parentcoll.Entities.Count > 0)
                {
                    foreach (var parent in parentcoll.Entities)
                    {
                        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.GetAttribute(pkattribute, new EntityReference()).Id.ToString());
                        }
                        else
                        {
                            ids.Add(parent.GetAttribute(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);
                }
                container.Log($"Adding relation condition for {attribute} in {ids.Count} values in {block}.{pkattribute}");
            }
            container.EndSection();
        }
コード例 #17
0
        /// <summary>
        /// Import entities to CRM from dictionary of blocks
        /// </summary>
        /// <param name="container"></param>
        /// <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(IExecutionContainer container, ShuffleBlocks blocks)
        {
            container.StartSection("ImportToCRM");
            if (definition == null)
            {
                throw new ArgumentNullException("Definition", "Shuffle definition must be specified to import data");
            }

            var created    = 0;
            var updated    = 0;
            var skipped    = 0;
            var deleted    = 0;
            var failed     = 0;
            var references = new EntityReferenceCollection();

            if (ShuffleDefinition.Blocks.Items.Any(b => (b is DataBlock data && data.Import != null) || b is SolutionBlock sol && sol.Import != null))
            {
                guidmap     = new Dictionary <Guid, Guid>();
                stoponerror = ShuffleDefinition.StopOnError;
                timeout     = ShuffleDefinition.TimeoutSpecified ? ShuffleDefinition.Timeout : -1;
                //double savedtimeout = -1;
                //if (timeout > -1)
                //{
                //    savedtimeout = SetTimeout();
                //}

                var totalBlocks  = ShuffleDefinition.Blocks.Items.Length;
                var currentBlock = 0;
                foreach (var block in ShuffleDefinition.Blocks.Items)
                {
                    currentBlock++;
                    SendStatus(totalBlocks, currentBlock, -1, -1);
                    if (block is DataBlock datablock)
                    {
                        var name = datablock.Name;
                        if (!blocks.ContainsKey(name))
                        {
                            blocks.Add(name, new EntityCollection());
                        }
                        var dataresult = ImportDataBlock(container, datablock, blocks[name]);
                        created += dataresult.Item1;
                        updated += dataresult.Item2;
                        skipped += dataresult.Item3;
                        deleted += dataresult.Item4;
                        failed  += dataresult.Item5;
                        references.AddRange(dataresult.Item6);
                    }
                    else if (block is SolutionBlock solutionblock)
                    {
                        var solutionresult = ImportSolutionBlock(solutionblock);
                        switch (solutionresult)
                        {
                        case ItemImportResult.Created: created++; break;

                        case ItemImportResult.Updated: updated++; break;

                        case ItemImportResult.Skipped: skipped++; break;

                        case ItemImportResult.Failed: failed++; break;
                        }
                    }
                }
                SendStatus(0, 0, 0, 0);
                //if (savedtimeout > -1)
                //{
                //    ResetTimeout(container, savedtimeout);
                //}
            }
            container.EndSection();
            return(new Tuple <int, int, int, int, int, EntityReferenceCollection>(created, updated, skipped, deleted, failed, references));
        }
コード例 #18
0
        private bool SaveEntity(IExecutionContainer container, Entity cdNewEntity, Entity cdMatchEntity, bool updateInactiveRecord, bool updateIdentical, int pos, string identifier)
        {
            container.StartSection("SaveEntity " + pos.ToString("000 ") + identifier);
            var recordSaved = false;

            if (string.IsNullOrWhiteSpace(identifier))
            {
                identifier = cdNewEntity.ToString();
            }
            var newOwner  = cdNewEntity.GetAttribute <EntityReference>("ownerid", null);
            var newState  = cdNewEntity.GetAttribute <OptionSetValue>("statecode", null);
            var newStatus = cdNewEntity.GetAttribute <OptionSetValue>("statuscode", null);
            var newActive = newState != null?container.GetActiveStates(cdNewEntity.LogicalName).Contains(newState.Value) : true;

            var nowActive = true;

            if ((newState == null) != (newStatus == null))
            {
                throw new InvalidDataException("When setting status of the record, both statecode and statuscode must be present");
            }
            if (!newActive)
            {
                container.Log("Removing state+status from entity to update");
                cdNewEntity.RemoveAttribute("statecode");
                cdNewEntity.RemoveAttribute("statuscode");
            }
            if (cdMatchEntity == null)
            {
                container.Create(cdNewEntity);
                recordSaved = true;
                SendLine(container, "{0:000} Created: {1}", pos, identifier);
            }
            else
            {
                var oldState  = cdMatchEntity.GetAttribute <OptionSetValue>("statecode", null);
                var oldActive = oldState != null?container.GetActiveStates(cdNewEntity.LogicalName).Contains(oldState.Value) : true;

                nowActive      = oldActive;
                cdNewEntity.Id = cdMatchEntity.Id;
                if (!oldActive && (newActive || updateInactiveRecord))
                {   // Inaktiv post som ska aktiveras eller uppdateras
                    container.SetState(cdNewEntity, 0, 1);
                    SendLine(container, "{0:000} Activated: {1} for update", pos, identifier);
                    nowActive = true;
                }

                if (nowActive)
                {
                    var updateattributes = cdNewEntity.Attributes.Keys.ToList();
                    if (updateattributes.Contains(container.Entity(cdNewEntity.LogicalName).PrimaryIdAttribute))
                    {
                        updateattributes.Remove(container.Entity(cdNewEntity.LogicalName).PrimaryIdAttribute);
                    }
                    if (updateIdentical || !EntityAttributesEqual(container, updateattributes, cdNewEntity, cdMatchEntity))
                    {
                        try
                        {
                            container.Update(cdNewEntity);
                            recordSaved = true;
                            SendLine(container, "{0:000} Updated: {1}", pos, identifier);
                        }
                        catch (Exception)
                        {
                            recordSaved = false;
                            SendLine(container, "{0:000} Update Failed: {1} {2} {3}", pos, identifier, cdNewEntity.LogicalName);
                        }
                    }
                    else
                    {
                        SendLine(container, "{0:000} Skipped: {1} (Identical)", pos, identifier);
                    }
                }
                else
                {
                    SendLine(container, "{0:000} Inactive: {1}", pos, identifier);
                }
                if (newOwner != null && !newOwner.Equals(cdMatchEntity.GetAttribute("ownerid", new EntityReference())))
                {
                    container.Principal(cdNewEntity).On(newOwner).Assign();

                    // cdNewEntity.Assign(newOwner);
                    SendLine(container, "{0:000} Assigned: {1} to {2} {3}", pos, identifier, newOwner.LogicalName, string.IsNullOrEmpty(newOwner.Name) ? newOwner.Id.ToString() : newOwner.Name);
                }
            }
            if (newActive != nowActive)
            {   // Active should be changed on the record
                var newStatusValue = newStatus.Value;
                if (cdNewEntity.LogicalName == "savedquery" && newState.Value == 1 && newStatusValue == 1)
                {   // Adjustment for inactive but unpublished view
                    newStatusValue = 2;
                }
                if (cdNewEntity.LogicalName == "duplicaterule")
                {
                    if (newStatusValue == 2)
                    {
                        container.PublishDuplicateRule(cdNewEntity);
                        SendLine(container, "{0:000} Publish Duplicate Rule: {1}", pos, identifier);
                    }
                    else
                    {
                        container.UnpublishDuplicateRule(cdNewEntity);
                        SendLine(container, "{0:000} Unpublish Duplicate Rule: {1}", pos, identifier);
                    }
                }
                else
                {
                    container.SetState(cdNewEntity, newState.Value, newStatusValue);
                    SendLine(container, "{0:000} SetState: {1}: {2}/{3}", pos, identifier, newState.Value, newStatus.Value);
                }
            }
            container.EndSection();
            return(recordSaved);
        }
コード例 #19
0
        private Tuple <int, int, int, int, int, EntityReferenceCollection> ImportDataBlock(IExecutionContainer container, DataBlock block, EntityCollection cEntities)
        {
            container.StartSection("ImportDataBlock");
            var created    = 0;
            var updated    = 0;
            var skipped    = 0;
            var deleted    = 0;
            var failed     = 0;
            var references = new EntityReferenceCollection();

            var name = block.Name;

            container.Log($"Block: {name}");
            SendStatus(name, null);
            SendLine(container);

            if (block.Import != null)
            {
                var includeid       = block.Import.CreateWithId;
                var save            = block.Import.Save;
                var delete          = block.Import.Delete;
                var updateinactive  = block.Import.UpdateInactive;
                var updateidentical = block.Import.UpdateIdentical;
                if (block.Import.OverwriteSpecified)
                {
                    SendLine(container, "DEPRECATED use of attribute Overwrite!");
                    save = block.Import.Overwrite ? SaveTypes.CreateUpdate : SaveTypes.CreateOnly;
                }
                var matchattributes  = GetMatchAttributes(block.Import.Match);
                var updateattributes = !updateidentical?GetUpdateAttributes(cEntities) : new List <string>();

                var preretrieveall = block.Import.Match?.PreRetrieveAll == true;

                SendLine(container);
                SendLine(container, $"Importing block {name} - {cEntities.Count()} records ");

                var i = 1;

                if (delete == DeleteTypes.All && (matchattributes.Count == 0))
                {   // All records shall be deleted, no match attribute defined, so just get all and delete all
                    var entity  = block.Entity;
                    var qDelete = new QueryExpression(entity);

                    qDelete.ColumnSet.AddColumn(container.Entity(entity).PrimaryNameAttribute);
                    var deleterecords = container.RetrieveMultiple(qDelete);
                    //var deleterecords = Entity.RetrieveMultiple(crmsvc, qDelete, log);
                    SendLine(container, $"Deleting ALL {entity} - {deleterecords.Count()} records");
                    foreach (var record in deleterecords.Entities)
                    {
                        SendLine(container, "{0:000} Deleting existing: {1}", i, record);
                        try
                        {
                            container.Delete(record);
                            deleted++;
                        }
                        catch (FaultException <OrganizationServiceFault> ex)
                        {
                            if (ex.Message.ToUpperInvariant().Contains("DOES NOT EXIST"))
                            {   // This may happen through delayed cascade delete in CRM
                                SendLine(container, "      ...already deleted");
                            }
                            else
                            {
                                throw;
                            }
                        }
                        i++;
                    }
                }
                var totalRecords = cEntities.Count();
                i = 1;
                EntityCollection cAllRecordsToMatch = null;
                foreach (var cdEntity in cEntities.Entities)
                {
                    var unique = cdEntity.Id.ToString();
                    SendStatus(-1, -1, totalRecords, i);
                    try
                    {
                        var oldid = cdEntity.Id;
                        var newid = Guid.Empty;

                        ReplaceGuids(container, cdEntity, includeid);
                        ReplaceUpdateInfo(cdEntity);
                        unique = GetEntityDisplayString(container, block.Import.Match, cdEntity);
                        SendStatus(null, unique);

                        if (!block.TypeSpecified || block.Type == EntityTypes.Entity)
                        {
                            #region Entity

                            if (matchattributes.Count == 0)
                            {
                                if (save == SaveTypes.Never || save == SaveTypes.UpdateOnly)
                                {
                                    skipped++;
                                    SendLine(container, "{0:000} Not saving: {1}", i, unique);
                                }
                                else
                                {
                                    if (!includeid)
                                    {
                                        cdEntity.Id = Guid.Empty;
                                    }
                                    if (SaveEntity(container, cdEntity, null, updateinactive, updateidentical, i, unique))
                                    {
                                        created++;
                                        newid = cdEntity.Id;
                                        references.Add(cdEntity.ToEntityReference());
                                    }
                                }
                            }
                            else
                            {
                                var matches = GetMatchingRecords(container, cdEntity, matchattributes, updateattributes, preretrieveall, ref cAllRecordsToMatch);
                                if (delete == DeleteTypes.All || (matches.Count() == 1 && delete == DeleteTypes.Existing))
                                {
                                    foreach (var cdMatch in matches.Entities)
                                    {
                                        SendLine(container, "{0:000} Deleting existing: {1}", i, unique);
                                        try
                                        {
                                            container.Delete(cdMatch);
                                            deleted++;
                                        }
                                        catch (FaultException <OrganizationServiceFault> ex)
                                        {
                                            if (ex.Message.ToUpperInvariant().Contains("DOES NOT EXIST"))
                                            {   // This may happen through cascade delete in CRM
                                                SendLine(container, "      ...already deleted");
                                            }
                                            else
                                            {
                                                throw;
                                            }
                                        }
                                    }
                                    matches.Entities.Clear();
                                }
                                if (matches.Count() == 0)
                                {
                                    if (save == SaveTypes.Never || save == SaveTypes.UpdateOnly)
                                    {
                                        skipped++;
                                        SendLine(container, "{0:000} Not creating: {1}", i, unique);
                                    }
                                    else
                                    {
                                        if (!includeid)
                                        {
                                            cdEntity.Id = Guid.Empty;
                                        }
                                        if (SaveEntity(container, cdEntity, null, updateinactive, updateidentical, i, unique))
                                        {
                                            created++;
                                            newid = cdEntity.Id;
                                            references.Add(cdEntity.ToEntityReference());
                                        }
                                    }
                                }
                                else if (matches.Count() == 1)
                                {
                                    var match = matches[0];
                                    newid = match.Id;
                                    if (save == SaveTypes.CreateUpdate || save == SaveTypes.UpdateOnly)
                                    {
                                        if (SaveEntity(container, cdEntity, match, updateinactive, updateidentical, i, unique))
                                        {
                                            updated++;
                                            references.Add(cdEntity.ToEntityReference());
                                        }
                                        else
                                        {
                                            skipped++;
                                        }
                                    }
                                    else
                                    {
                                        skipped++;
                                        SendLine(container, "{0:000} Exists: {1}", i, unique);
                                    }
                                }
                                else
                                {
                                    failed++;
                                    SendLine(container, $"Import object matches {matches.Count()} records in target database!");
                                    SendLine(container, unique);
                                }
                            }
                            if (!oldid.Equals(Guid.Empty) && !newid.Equals(Guid.Empty) && !oldid.Equals(newid) && !guidmap.ContainsKey(oldid))
                            {
                                container.Log("Mapping IDs: {0} ==> {1}", oldid, newid);
                                guidmap.Add(oldid, newid);
                            }

                            #endregion Entity
                        }
                        else if (block.Type == EntityTypes.Intersect)
                        {
                            #region Intersect

                            if (cdEntity.Attributes.Count != 2)
                            {
                                throw new ArgumentOutOfRangeException("Attributes", cdEntity.Attributes.Count, "Invalid Attribute count for intersect object");
                            }
                            var intersect = block.IntersectName;
                            if (string.IsNullOrEmpty(intersect))
                            {
                                intersect = cdEntity.LogicalName;
                            }

                            var ref1 = (EntityReference)cdEntity.Attributes.ElementAt(0).Value;
                            var ref2 = (EntityReference)cdEntity.Attributes.ElementAt(1).Value;

                            var party1 = new Entity(ref1.LogicalName, ref1.Id); //Entity.InitFromNameAndId(ref1.LogicalName, ref1.Id, crmsvc, log);
                            var party2 = new Entity(ref2.LogicalName, ref2.Id); //Entity.InitFromNameAndId(ref2.LogicalName, ref2.Id, crmsvc, log);
                            try
                            {
                                container.Associate(party1, party2, intersect);
                                //party1.Associate(party2, intersect);
                                created++;
                                SendLine(container, "{0} Associated: {1}", i.ToString().PadLeft(3, '0'), name);
                            }
                            catch (Exception ex)
                            {
                                if (ex.Message.Contains("duplicate"))
                                {
                                    SendLine(container, "{0} Association exists: {1}", i.ToString().PadLeft(3, '0'), name);
                                    skipped++;
                                }
                                else
                                {
                                    throw;
                                }
                            }

                            #endregion Intersect
                        }
                    }
                    catch (Exception ex)
                    {
                        failed++;
                        SendLine(container, $"\n*** Error record: {unique} ***\n{ex.Message}");
                        container.Log(ex);
                        if (stoponerror)
                        {
                            throw;
                        }
                    }
                    i++;
                }

                SendLine(container, $"Created: {created} Updated: {updated} Skipped: {skipped} Deleted: {deleted} Failed: {failed}");
            }
            container.EndSection();
            return(new Tuple <int, int, int, int, int, EntityReferenceCollection>(created, updated, skipped, deleted, failed, references));
        }
コード例 #20
0
        private EntityCollection ExportDataBlock(IExecutionContainer container, ShuffleBlocks blocks, DataBlock block)
        {
            container.StartSection("ExportDataBlock");
            container.Log($"Block: {block.Name}");
            EntityCollection cExportEntities = null;

            if (block.Export != null)
            {
                #region Define attributes

                var attributes      = block.Export.Items.Where(i => i is DataBlockExportAttributes).FirstOrDefault() as DataBlockExportAttributes;
                var allcolumns      = false;
                var lAttributes     = new List <string>();
                var lNullAttributes = new List <string>();
                if (attributes != null)
                {
                    foreach (var attribute in attributes.Attribute)
                    {
                        var attr = attribute.Name;
                        container.Log($"Adding column: {attr}");
                        lAttributes.Add(attr.Replace("*", "%"));
                        if (attr.Contains("*"))
                        {
                            allcolumns = true;
                            container.Log("Found wildcard");
                        }
                        else
                        {
                            if (attribute.IncludeNull)
                            {
                                lNullAttributes.Add(attr);
                            }
                        }
                    }
                }
                else
                {
                    allcolumns = true;
                    lAttributes.Add("*");
                    container.Log("Attributes not specified, retrieving all");
                }

                #endregion Define attributes

                var fetchxml = block.Export.Items.Where(i => i is string).FirstOrDefault() as string;
                if (!string.IsNullOrWhiteSpace(fetchxml))
                {
                    container.StartSection("Export entity using FetchXML");
#if DEBUG
                    container.Log($"FetchXML:\n{fetchxml}");
#endif
                    cExportEntities = container.RetrieveMultiple(new FetchExpression(fetchxml));

                    container.EndSection();
                }
                else if (!block.TypeSpecified || block.Type == EntityTypes.Entity)
                {
                    #region QueryExpression Entity

                    container.StartSection($"Export entity {block.Entity}");
                    var qExport = new QueryExpression(block.Entity);
                    if (block.Export.ActiveOnly)
                    {
                        Query.AppendConditionActive(qExport.Criteria);
                        //CintQryExp.AppendConditionActive(qExport.Criteria);
                    }

                    if (block.Relation != null)
                    {
                        foreach (var relation in block.Relation)
                        {
                            AddRelationFilter(container, blocks, block.Entity, relation, qExport.Criteria);
                        }
                    }
                    foreach (var filter in block.Export.Items.Where(i => i is DataBlockExportFilter).Cast <DataBlockExportFilter>())
                    {
                        AddFilter(container, qExport, filter);
                    }
                    foreach (var sort in block.Export.Items.Where(i => i is DataBlockExportSort).Cast <DataBlockExportSort>())
                    {
                        qExport.AddOrder(sort.Attribute, sort.Type == SortTypes.Desc ? OrderType.Descending : OrderType.Ascending);
                    }
                    if (allcolumns)
                    {
                        qExport.ColumnSet = new ColumnSet(true);
                    }
                    else
                    {
                        foreach (var attr in lAttributes)
                        {
                            qExport.ColumnSet.AddColumn(attr);
                        }
                    }
#if DEBUG
                    container.Log("Converting to FetchXML");
                    try
                    {
                        var fetch = container.ConvertToFetchXml(qExport);
                        container.Log($"Exporting {block.Entity}:\n{fetch}");
                    }
                    catch (Exception ex)
                    {
                        container.Log("Conversion error:");
                        container.Log(ex);
                    }
#endif
                    cExportEntities = container.RetrieveMultiple(qExport);
                    if (allcolumns)
                    {
                        SelectAttributes(container, cExportEntities, lAttributes, lNullAttributes);
                    }
                    SendLine(container, $"Block {block.Name} - {cExportEntities.Count()} records");
                    container.EndSection();

                    #endregion QueryExpression Entity
                }
                else if (block.Type == EntityTypes.Intersect)
                {
                    #region FetchXML Intersect

                    container.StartSection($"Export intersect {block.Entity}");
                    var xDoc    = new XmlDocument();
                    var xEntity = FetchXML.Create(xDoc, block.Entity);
                    FetchXML.AddAttribute(xEntity, lAttributes.ToArray());

                    if (block.Relation != null)
                    {
                        foreach (var relation in block.Relation)
                        {
                            AddRelationFilter(container, blocks, relation, xEntity);
                        }
                    }

                    var fetch = xDoc.OuterXml;
                    //Imran: Removed because this is causing invalid Xml errors. Could not see the point of having these placeholders.
                    //fetch = fetch.Replace("<fetch ", "<fetch {0} {1} ");    // Detta för att se till att CrmServiceProxy.RetrieveMultiple kan hantera paging
#if DEBUG
                    container.Log($"Exporting intersect entity {block.Entity}\n{fetch}");
#endif
                    var qExport = new FetchExpression(fetch);
                    cExportEntities = container.RetrieveMultiple(qExport);
                    foreach (var entity in cExportEntities.Entities)
                    {
                        var newattributes = new List <KeyValuePair <string, object> >();
                        foreach (var attr in entity.Attributes)
                        {
                            if (attr.Value is Guid guid)
                            {
                                var attrname      = attr.Key;
                                var relatedentity = attrname.Substring(0, attrname.Length - (attrname.EndsWith("idone") || attrname.EndsWith("idtwo") ? 5 : 2));
                                if (!newattributes.Contains(new KeyValuePair <string, object>(attrname, new EntityReference(relatedentity, guid))))
                                {
                                    container.Log($"Adding Attribute {attrname} - Related entity {relatedentity}");
                                    newattributes.Add(new KeyValuePair <string, object>(attrname, new EntityReference(relatedentity, guid)));
#if DEBUG
                                    container.Log($"{attrname} added");
#endif
                                }
                                else
                                {
#if DEBUG
                                    container.Log($"{attrname} already exists.");
#endif
                                }
                            }
                        }
                        foreach (var newattr in newattributes)
                        {
#if DEBUG
                            container.Log($"Entity {entity.LogicalName} contains attribute {newattr.Key}: {entity.Attributes.Contains(newattr.Key)}");
#endif
                            if (!entity.Attributes.Contains(newattr.Key))
                            {
                                entity.Attributes.Add(newattr.Key, newattr.Value);
                            }
                        }
                    }
                    container.EndSection();

                    #endregion FetchXML Intersect
                }

                container.Log($"Returning {cExportEntities.Count()} records");
            }
            container.EndSection();
            return(cExportEntities);
        }
コード例 #21
0
        private EntityCollection GetMatchingRecords(IExecutionContainer container, Entity cdEntity, List <string> matchattributes, List <string> updateattributes, bool preretrieveall, ref EntityCollection cAllRecordsToMatch)
        {
            container.StartSection(MethodBase.GetCurrentMethod().Name);
            EntityCollection matches = null;
            var allattributes        = new List <string>
            {
                container.Entity(cdEntity.LogicalName).PrimaryIdAttribute
            };

            if (cdEntity.Contains("ownerid"))
            {
                allattributes.Add("ownerid");
            }
            if (cdEntity.Contains("statecode") || cdEntity.Contains("statuscode"))
            {
                allattributes.Add("statecode");
                allattributes.Add("statuscode");
            }
            allattributes = allattributes.Union(matchattributes.Union(updateattributes)).ToList();
            if (preretrieveall)
            {
                if (cAllRecordsToMatch == null)
                {
                    cAllRecordsToMatch = GetAllRecordsForMatching(container, allattributes, cdEntity);
                }
                matches = GetMatchingRecordsFromPreRetrieved(container, matchattributes, cdEntity, cAllRecordsToMatch);
            }
            else
            {
                var qMatch = new QueryExpression(cdEntity.LogicalName)
                {
                    // We need to be able to see if any attributes have changed, so lets make sure matching records have all the attributes that will be updated
                    ColumnSet = new ColumnSet(allattributes.ToArray())
                };

                foreach (var matchattr in matchattributes)
                {
                    object value = null;
                    if (cdEntity.Contains(matchattr))
                    {
                        value = container.AttributeAsBaseType(cdEntity, matchattr, null, false);
                    }
                    else if (matchattr == container.Entity(cdEntity.LogicalName).PrimaryIdAttribute)
                    {
                        value = cdEntity.Id;
                    }
                    if (value != null)
                    {
                        Query.AppendCondition(qMatch.Criteria, LogicalOperator.And, matchattr, Microsoft.Xrm.Sdk.Query.ConditionOperator.Equal, value);
                    }
                    else
                    {
                        Query.AppendCondition(qMatch.Criteria, LogicalOperator.And, matchattr, Microsoft.Xrm.Sdk.Query.ConditionOperator.Null, null);
                    }
                }
#if DEBUG
                container.Log($"Finding matches for {cdEntity.LogicalName}:\n{container.ConvertToFetchXml(qMatch)}");
#endif
                matches = container.RetrieveMultiple(qMatch);
            }
            container.EndSection();
            return(matches);
        }
コード例 #22
0
        private void ExportSolutionBlock(IExecutionContainer container, SolutionBlock block)
        {
            container.StartSection("ExportSolutionBlock");
            var name = block.Name;

            container.Log("Block: {0}", name);
            var path = block.Path;
            var file = block.File;

            if (string.IsNullOrWhiteSpace(path) && !string.IsNullOrWhiteSpace(definitionpath))
            {
                path  = definitionpath;
                path += path.EndsWith("\\") ? "" : "\\";
            }
            if (string.IsNullOrWhiteSpace(file))
            {
                file = name;
            }
            if (block.Export != null)
            {
                var type          = block.Export.Type;
                var setversion    = block.Export.SetVersion;
                var publish       = block.Export.PublishBeforeExport;
                var targetversion = block.Export.TargetVersion;

                var cdSolution     = GetAndVerifySolutionForExport(name);
                var currentversion = new Version(cdSolution.GetAttribute("version", "1.0.0.0"));

                SendLine(container, "Solution: {0} {1}", name, currentversion);

                if (!string.IsNullOrWhiteSpace(setversion))
                {
                    SetNewSolutionVersion(container, setversion, cdSolution, currentversion);
                }

                if (publish)
                {
                    SendLine(container, "Publishing customizations");
                    container.Execute(new PublishAllXmlRequest());
                }

                var req = new ExportSolutionRequest()
                {
                    SolutionName = name
                };
#if Crm8
                if (!string.IsNullOrWhiteSpace(targetversion))
                {
                    req.TargetVersion = targetversion;
                }
#endif
                if (block.Export.Settings != null)
                {
                    req.ExportAutoNumberingSettings          = block.Export.Settings.AutoNumbering;
                    req.ExportCalendarSettings               = block.Export.Settings.Calendar;
                    req.ExportCustomizationSettings          = block.Export.Settings.Customization;
                    req.ExportEmailTrackingSettings          = block.Export.Settings.EmailTracking;
                    req.ExportGeneralSettings                = block.Export.Settings.General;
                    req.ExportMarketingSettings              = block.Export.Settings.Marketing;
                    req.ExportOutlookSynchronizationSettings = block.Export.Settings.OutlookSync;
                    req.ExportRelationshipRoles              = block.Export.Settings.RelationshipRoles;
                    req.ExportIsvConfig = block.Export.Settings.IsvConfig;
                }

                if (type == SolutionTypes.Managed || type == SolutionTypes.Both)
                {
                    var filename = path + file + "_managed.zip";
                    SendLine(container, "Exporting solution to: {0}", filename);
                    req.Managed = true;
                    var exportSolutionResponse = (ExportSolutionResponse)container.Execute(req);
                    var exportXml = exportSolutionResponse.ExportSolutionFile;
                    File.WriteAllBytes(filename, exportXml);
                }
                if (type == SolutionTypes.Unmanaged || type == SolutionTypes.Both)
                {
                    var filename = path + file + ".zip";
                    SendLine(container, $"Exporting solution to: {filename}");
                    req.Managed = false;
                    var exportSolutionResponse = (ExportSolutionResponse)container.Execute(req);
                    var exportXml = exportSolutionResponse.ExportSolutionFile;
                    File.WriteAllBytes(filename, exportXml);
                }
            }
            container.EndSection();
        }