private void AddReferenceConfigJoins(LinkEntity linkToReferenced, Entity thisEntity, string field)
        {
            var referencedType       = XrmEntity.GetLookupType(thisEntity.GetFieldValue(field));
            var referencedTypeConfig = XrmRecordService.GetTypeConfigs().GetFor(referencedType);

            if (referencedTypeConfig != null && referencedTypeConfig.UniqueChildFields != null)
            {
                foreach (var uniqueField in referencedTypeConfig.UniqueChildFields)
                {
                    var theValue = thisEntity.GetFieldValue($"{field}.{uniqueField}");
                    if (theValue == null)
                    {
                        linkToReferenced.LinkCriteria.AddCondition(new ConditionExpression(uniqueField, ConditionOperator.Null));
                    }
                    else if (theValue is EntityReference)
                    {
                        var name = XrmEntity.GetLookupName(theValue);
                        var type = XrmEntity.GetLookupType(theValue);
                        var nextLinkToReferenced = linkToReferenced.AddLink(type, uniqueField, XrmService.GetPrimaryKeyField(type));
                        if (name == null)
                        {
                            nextLinkToReferenced.LinkCriteria.AddCondition(XrmService.GetPrimaryNameField(type), ConditionOperator.Null);
                        }
                        else
                        {
                            nextLinkToReferenced.LinkCriteria.AddCondition(XrmService.GetPrimaryNameField(type), ConditionOperator.Equal, name);
                            AddReferenceConfigJoins(nextLinkToReferenced, thisEntity, $"{field}.{uniqueField}");
                        }
                    }
                    else
                    {
                        linkToReferenced.LinkCriteria.AddCondition(new ConditionExpression(uniqueField, ConditionOperator.Equal, XrmService.ConvertToQueryValue(uniqueField, referencedType, theValue)));
                    }
                }
            }
        }
Пример #2
0
        public void ProcessExport(IEnumerable <ExportRecordType> exports, bool includeNotes, bool includeNNBetweenEntities, LogController controller
                                  , Action <Entity> processEntity, Action <Entity> processAssociation)
        {
            if (exports == null || !exports.Any())
            {
                throw new Exception("Error No Record Types To Export");
            }
            var countToExport  = exports.Count();
            var countsExported = 0;
            var exported       = new Dictionary <string, List <Entity> >();

            foreach (var exportType in exports)
            {
                var type           = exportType.RecordType == null ? null : exportType.RecordType.Key;
                var thisTypeConfig = XrmRecordService.GetTypeConfigs().GetFor(type);
                controller.UpdateProgress(countsExported++, countToExport, string.Format("Querying {0} Records", type));
                var conditions = new List <ConditionExpression>();
                if (type == "list")
                {
                    conditions.Add(new ConditionExpression("type", ConditionOperator.Equal, XrmPicklists.ListType.Dynamic));
                }
                if (type == "knowledgearticle")
                {
                    conditions.Add(new ConditionExpression("islatestversion", ConditionOperator.Equal, true));
                }
                //doesn't work for too many notes
                //should have option on each or all entities for notes maybe
                IEnumerable <Entity> entities;
                switch (exportType.Type)
                {
                case ExportType.AllRecords:
                {
                    entities = XrmService.RetrieveAllAndClauses(type, conditions)
                               .Where(e => !CheckIgnoreForExport(exportType, e))
                               .ToArray();
                    break;
                }

                case ExportType.FetchXml:
                {
                    var queryExpression = XrmService.ConvertFetchToQueryExpression(exportType.FetchXml);
                    queryExpression.ColumnSet = new ColumnSet(true);
                    entities = queryExpression.PageInfo != null && queryExpression.PageInfo.Count > 0
                                ? XrmService.RetrieveFirstX(queryExpression, queryExpression.PageInfo.Count)
                                : XrmService.RetrieveAll(queryExpression);
                    entities = entities
                               .Where(e => !CheckIgnoreForExport(exportType, e))
                               .ToArray();
                    break;
                }

                case ExportType.SpecificRecords:
                {
                    var primaryKey = XrmService.GetPrimaryKeyField(type);
                    var ids        = exportType.SpecificRecordsToExport == null
                                ? new string[0]
                                : exportType.SpecificRecordsToExport
                                     .Select(r => r.Record == null ? null : r.Record.Id)
                                     .Where(s => !s.IsNullOrWhiteSpace()).Distinct().ToArray();
                    entities = ids
                               .Select(id => XrmService.Retrieve(type, new Guid(id)))
                               .ToArray();
                    break;
                }

                default:
                {
                    throw new NotImplementedException(string.Format("No Export Implemented For {0} {1} For {2} Records", typeof(ExportType).Name, exportType.Type, type));
                }
                }

                var excludeFields = exportType.IncludeAllFields
                    ? new string[0]
                    : XrmService.GetFields(exportType.RecordType.Key).Except(exportType.IncludeOnlyTheseFields.Select(f => f.RecordField == null ? null : f.RecordField.Key).Distinct().ToArray());

                if (thisTypeConfig != null)
                {
                    //which need to include the fields if they are needed for parentchild configs
                    excludeFields = excludeFields.Except(new[] { thisTypeConfig.ParentLookupField }).ToArray();
                    if (thisTypeConfig.UniqueChildFields != null)
                    {
                        excludeFields = excludeFields.Except(thisTypeConfig.UniqueChildFields).ToArray();
                    }

                    var fieldsToIncludeInParent = XrmRecordService.GetTypeConfigs().GetParentFieldsRequiredForComparison(type);
                    var thisTypesParentsConfig  = XrmRecordService.GetTypeConfigs().GetFor(thisTypeConfig.ParentLookupType);
                    if (fieldsToIncludeInParent != null)
                    {
                        //if the parent also has a config then we need to use it when matching the parent
                        //e.g. portal web page access rules -> web page where the web page may be a master or child web page
                        //so lets include the parents config fields as aliased fields in the exported entity
                        foreach (var item in entities)
                        {
                            var parentId = item.GetLookupGuid(thisTypeConfig.ParentLookupField);
                            if (parentId.HasValue)
                            {
                                var parent = XrmService.Retrieve(thisTypeConfig.ParentLookupType, parentId.Value, fieldsToIncludeInParent);
                                item.Attributes.AddRange(parent.Attributes.Select(f => new KeyValuePair <string, object>($"{thisTypeConfig.ParentLookupField}.{f.Key}", new AliasedValue(thisTypeConfig.ParentLookupType, f.Key, f.Value))));
                            }
                        }
                    }

                    var lookupFieldsEnsureNamePopulated = new List <string>();
                    if (thisTypeConfig.ParentLookupField != null)
                    {
                        lookupFieldsEnsureNamePopulated.Add(thisTypeConfig.ParentLookupField);
                    }
                    if (thisTypeConfig.UniqueChildFields != null)
                    {
                        lookupFieldsEnsureNamePopulated.AddRange(thisTypeConfig.UniqueChildFields.Where(f => XrmService.IsLookup(f, thisTypeConfig.Type)));
                    }
                    foreach (var field in lookupFieldsEnsureNamePopulated)
                    {
                        controller.UpdateProgress(countsExported++, countToExport, string.Format("Populating Empty Lookups For {0} Records", type));
                        foreach (var item in entities)
                        {
                            var entityReference = item.GetField(field) as EntityReference;
                            if (entityReference != null && entityReference.Name == null)
                            {
                                var referencedTypeNameField = XrmService.GetPrimaryNameField(entityReference.LogicalName);
                                var referencedRecord        = XrmService.Retrieve(entityReference.LogicalName, entityReference.Id, new[] { referencedTypeNameField });
                                entityReference.Name = referencedRecord.GetStringField(referencedTypeNameField);
                            }
                        }
                    }
                }

                var primaryField = XrmService.GetPrimaryNameField(exportType.RecordType.Key);
                if (excludeFields.Contains(primaryField))
                {
                    excludeFields = excludeFields.Except(new[] { primaryField }).ToArray();
                }

                if (exportType.ExplicitValuesToSet != null)
                {
                    foreach (var field in exportType.ExplicitValuesToSet)
                    {
                        var parseFieldValue = XrmRecordService.ToEntityValue(field.ClearValue ? null : field.ValueToSet);
                        foreach (var entity in entities)
                        {
                            entity.SetField(field.FieldToSet.Key, parseFieldValue, XrmService);
                        }
                        if (excludeFields.Contains(field.FieldToSet.Key))
                        {
                            excludeFields = excludeFields.Except(new[] { field.FieldToSet.Key }).ToArray();
                        }
                    }
                }

                var fieldsAlwaysExclude = new[] { "calendarrules" };
                excludeFields = excludeFields.Union(fieldsAlwaysExclude).ToArray();

                var toDo = entities.Count();
                var done = 0;
                foreach (var entity in entities)
                {
                    controller.UpdateLevel2Progress(done++, toDo, string.Format("Processing {0} Records", type));
                    entity.RemoveFields(excludeFields);
                    processEntity(entity);
                }
                controller.TurnOffLevel2();
                if (!exported.ContainsKey(type))
                {
                    exported.Add(type, new List <Entity>());
                }
                exported[type].AddRange(entities);
                if (includeNotes)
                {
                    controller.LogLiteral(string.Format("Querying Notes For {0} Records", type));
                    var notes = XrmService
                                .RetrieveAllOrClauses("annotation",
                                                      new[] { new ConditionExpression("objecttypecode", ConditionOperator.Equal, type) });

                    toDo = notes.Count();
                    done = 0;
                    foreach (var note in notes)
                    {
                        var objectId = note.GetLookupGuid("objectid");
                        if (objectId.HasValue && entities.Select(e => e.Id).Contains(objectId.Value))
                        {
                            controller.UpdateLevel2Progress(done++, toDo, string.Format("Processing Notes For {0} Records", type));
                            processEntity(note);
                        }
                    }
                    controller.TurnOffLevel2();
                }
                controller.TurnOffLevel2();
            }
            var relationshipsDone = new List <string>();

            if (includeNNBetweenEntities)
            {
                countToExport  = exports.Count();
                countsExported = 0;
                foreach (var type in exported.Keys)
                {
                    controller.UpdateProgress(countsExported++, countToExport, string.Format("Exporting {0} Associations", type));
                    var nnRelationships = XrmService.GetEntityManyToManyRelationships(type)
                                          .Where(
                        r =>
                        exported.Keys.Contains(r.Entity1LogicalName) && exported.Keys.Contains(r.Entity2LogicalName));

                    foreach (var item in nnRelationships)
                    {
                        var type1 = item.Entity1LogicalName;
                        var type2 = item.Entity2LogicalName;
                        if (!relationshipsDone.Contains(item.SchemaName))
                        {
                            controller.LogLiteral(string.Format("Querying {0} Associations", item.SchemaName));
                            var associations = XrmService.RetrieveAllEntityType(item.IntersectEntityName, null);
                            var toDo         = associations.Count();
                            var done         = 0;
                            foreach (var association in associations)
                            {
                                controller.UpdateLevel2Progress(done++, toDo, string.Format("Processing Notes For {0} Records", type));
                                if (exported[type1].Any(e => e.Id == association.GetGuidField(item.Entity1IntersectAttribute)) &&
                                    exported[type2].Any(e => e.Id == association.GetGuidField(item.Entity2IntersectAttribute)))
                                {
                                    processAssociation(association);
                                }
                            }
                            relationshipsDone.Add(item.SchemaName);
                            controller.TurnOffLevel2();
                        }
                    }
                }
            }
            controller.TurnOffLevel2();
        }
Пример #3
0
        private void CheckLoadCache(IEnumerable <string> recordsReferenced)
        {
            var loadTheseOnes = recordsReferenced.ToList();
            var typeConfigs   = XrmRecordService.GetTypeConfigs();

            foreach (var one in loadTheseOnes.ToArray())
            {
                if (_dontCacheTheseTypes.Contains(one))
                {
                    loadTheseOnes.Remove(one);
                }
                if (_cachedRecords.ContainsKey(one))
                {
                    loadTheseOnes.Remove(one);
                }
                else
                {
                    var typeConfig = typeConfigs.GetFor(one);
                    if (typeConfig != null)
                    {
                        loadTheseOnes.Remove(one);
                    }
                }
            }

            var getMultipleResponses = XrmService.ExecuteMultiple(loadTheseOnes.Select(rt =>
            {
                var matchFilters = _matchFilters.ContainsKey(rt)
                    ? _matchFilters[rt]
                    : new ConditionExpression[0];
                var query = new QueryExpression(rt)
                {
                    ColumnSet = new ColumnSet(true),
                    TopCount  = _maxCacheCount
                };
                query.Criteria.Conditions.AddRange(matchFilters);
                return(new RetrieveMultipleRequest
                {
                    Query = query
                });
            }).ToArray());


            if (getMultipleResponses.Any())
            {
                try
                {
                    var i = 0;
                    foreach (var response in getMultipleResponses)
                    {
                        var type = loadTheseOnes.ElementAt(i);
                        if (response.Fault != null)
                        {
                            Response.AddImportError(new DataImportResponseItem(
                                                        $"Error Loading Target Records Cache for {type})", new FaultException <OrganizationServiceFault>(response.Fault, response.Fault.Message)));
                        }
                        else
                        {
                            var records = ((RetrieveMultipleResponse)response.Response).EntityCollection.Entities;
                            if (!_cachedRecords.ContainsKey(type))
                            {
                                _cachedRecords.Add(type, new Dictionary <string, Dictionary <string, List <Entity> > >());
                            }
                            var primaryKey = XrmService.GetPrimaryKeyField(type);
                            if (!_cachedRecords[type].ContainsKey(primaryKey))
                            {
                                _cachedRecords[type].Add(primaryKey, new Dictionary <string, List <Entity> >());
                            }

                            foreach (var record in records)
                            {
                                var cacheMatchString = record.Id.ToString();
                                if (!_cachedRecords[type][primaryKey].ContainsKey(cacheMatchString))
                                {
                                    _cachedRecords[type][primaryKey].Add(cacheMatchString, new List <Entity>());
                                }
                                _cachedRecords[type][primaryKey][cacheMatchString].Add(record);
                            }
                            var primaryNameField = XrmService.GetPrimaryNameField(type);
                            if (primaryNameField != null)
                            {
                                if (!_cachedRecords[type].ContainsKey(primaryNameField))
                                {
                                    _cachedRecords[type].Add(primaryNameField, new Dictionary <string, List <Entity> >());
                                }
                                foreach (var record in records)
                                {
                                    var cacheMatchString = XrmService.GetFieldAsMatchString(type, primaryNameField, record.GetStringField(primaryNameField));
                                    if (!_cachedRecords[type][primaryNameField].ContainsKey(cacheMatchString))
                                    {
                                        _cachedRecords[type][primaryNameField].Add(cacheMatchString, new List <Entity>());
                                    }
                                    _cachedRecords[type][primaryNameField][cacheMatchString].Add(record);
                                }
                            }
                        }
                        i++;
                    }
                }
                catch (Exception ex)
                {
                    Response.AddImportError(new DataImportResponseItem(
                                                $"Error Loading Target Records Cache ({string.Join(",", loadTheseOnes)})", ex));
                }
            }
        }