Пример #1
0
 public NavigationMutationInfo(MutationContext mutationContext, INavigation navigation, EntityMutationInfo entityMutationInfo) : base(mutationContext, entityMutationInfo)
 {
     Navigation = navigation;
     PermissionNavigationPropertyInfo = mutationContext.PermissionEntityTypeBuilder.PropertyMap[navigation];
     EntityMutationInfo = entityMutationInfo;
 }
Пример #2
0
 public MemberMutationInfo(MutationContext mutationContext, EntityMutationInfo entityMutationInfo)
 {
     MutationContext    = mutationContext;
     EntityMutationInfo = entityMutationInfo;
 }
Пример #3
0
 public PropertyMutationInfo(MutationContext mutationContext, IProperty property, EntityMutationInfo entityMutationInfo) : base(mutationContext, entityMutationInfo)
 {
     Property = property;
 }
Пример #4
0
 public ReferenceMutationInfo(MutationContext mutationContext, INavigation navigation, EntityMutationInfo entityMutationInfo) : base(mutationContext, navigation, entityMutationInfo)
 {
 }
Пример #5
0
        public EntityMutationInfo(IEntityType entityType, JObject jObject, MutationContext mutationContext)
        {
            IsReference            = jObject.ContainsKey("$ref");
            JObject                = jObject;
            MutationContext        = mutationContext;
            EntityType             = entityType;
            Properties             = new Dictionary <IProperty, PropertyMutationInfo>();
            References             = new Dictionary <INavigation, ReferenceMutationInfo>();
            Collections            = new Dictionary <INavigation, CollectionMutationInfo>();
            Entity                 = Activator.CreateInstance(entityType.ClrType);
            RuleMap                = mutationContext.RuleMaps.Where(ruleMap => ruleMap.CanHandle(entityType.ClrType, mutationContext.SecurityContext)).BuildRuleMap();
            PermissionType         = mutationContext.PermissionEntityTypeBuilder.TypeMap[entityType];
            SelfPermissionProperty = mutationContext.PermissionEntityTypeBuilder.TypeMap[entityType].GetProperty("SelfPermission");
            PrimaryKey             = entityType.FindPrimaryKey();

            var jProperties = jObject.Properties();
            var properties  = entityType.GetProperties();
            var navigations = entityType.GetNavigations();
            var references  = navigations.Where(navigation => !navigation.IsCollection());
            var collections = navigations.Where(navigation => navigation.IsCollection());

            Properties  = properties.ToDictionary(property => property, property => new PropertyMutationInfo(MutationContext, property, this));
            References  = references.ToDictionary(reference => reference, reference => new ReferenceMutationInfo(MutationContext, reference, this));
            Collections = collections.ToDictionary(collection => collection, collection => new CollectionMutationInfo(MutationContext, collection, this));


            PropertyTuples = jProperties.Join(properties, jp => jp.Name.ToPascalCase(), p => p.Name, (jp, p) => new PropertyPropertyTuple {
                JProperty = jp, Property = p
            }).ToHashSet();
            ReferenceTuples = jProperties.Join(references, jp => jp.Name.ToPascalCase(), p => p.Name, (jp, p) => new NavigationPropertyTuple {
                JProperty = jp, Navigation = p
            }).ToHashSet();
            CollectionTuples = jProperties.Join(collections, jp => jp.Name.ToPascalCase(), p => p.Name, (jp, p) => new NavigationPropertyTuple {
                JProperty = jp, Navigation = p
            }).Where(tuple => tuple.JProperty.Values().Any()).ToHashSet();

            var primaryKeyTuples           = PrimaryKey.Properties.Join(PropertyTuples, pkp => pkp, pt => pt.Property, (pkp, pt) => pkp).ToArray();
            var isPrimaryKeySet            = primaryKeyTuples.Length == PrimaryKey.Properties.Count;
            var nonGeneratedPropertyTuples = PropertyTuples.Where(pt => !pt.Property.ValueGenerated.HasFlag(ValueGenerated.OnAdd));

            if (jObject.ContainsKey("$isCreation"))
            {
                State = EntityState.Added;
            }
            else if (isPrimaryKeySet)
            {
                if (jObject.ContainsKey("$isDeletion"))
                {
                    State = EntityState.Deleted;
                }
                else if (jObject.ContainsKey("$isEdition") || nonGeneratedPropertyTuples.Any() || References.Values.Any(@ref => @ref.IsModified) || Collections.Values.Any(col => col.IsModified))
                {
                    State = EntityState.Modified;
                }
                else
                {
                    State = EntityState.Unchanged;
                }
            }
            else if (PrimaryKey.Properties[0].ValueGenerated == ValueGenerated.OnAdd)
            {
                State = EntityState.Added;
            }
            else
            {
                State = EntityState.Unchanged;
            }

            foreach (var propertyTuple in PropertyTuples)
            {
                var value = propertyTuple.JProperty.Value.ToObject(propertyTuple.Property.ClrType, mutationContext.JsonSerializer);
                propertyTuple.Property.AsProperty().Setter.SetClrValue(Entity, value);
                Properties[propertyTuple.Property].IsModified = !(propertyTuple.Property.ValueGenerated.HasFlag(ValueGenerated.OnAdd) && propertyTuple.Property.IsPrimaryKey());
                Properties[propertyTuple.Property].IsTouched  = true;
                var containingForeignKeys = propertyTuple.Property.GetContainingForeignKeys();
                foreach (var containingForeignKey in containingForeignKeys)
                {
                    var navigation = containingForeignKey.GetNavigation(true);
                    if (navigation != null)
                    {
                        var reference = References[containingForeignKey.GetNavigation(true)];
                        reference.IsModified = true;
                        var keyProperty1 = propertyTuple.Property.FindFirstPrincipal();
                        if (reference.TargetEntityMutationInfo == null)
                        {
                            var propertyValue = (JObject)jObject.Property(reference.Navigation.Name.ToCamelCase())?.Value;
                            if (propertyValue == null)
                            {
                                propertyValue = new JObject();
                            }
                            if (!propertyValue.ContainsKey(keyProperty1.Name.ToCamelCase()))
                            {
                                propertyValue.Add(keyProperty1.Name.ToCamelCase(), JToken.FromObject(value));
                            }
                            reference.TargetEntityMutationInfo      = new EntityMutationInfo(containingForeignKey.PrincipalEntityType, propertyValue, MutationContext);
                            reference.TargetEntityMutationInfo.Root = State == EntityState.Added;
                        }
                        else
                        {
                            keyProperty1.AsProperty().Setter.SetClrValue(reference.TargetEntityMutationInfo.Entity, propertyTuple.Property.GetGetter().GetClrValue(Entity));
                        }
                    }
                }
            }
            foreach (var referenceTuple in ReferenceTuples)
            {
                var referencedEntityMutationInfo = References[referenceTuple.Navigation].TargetEntityMutationInfo;
                if (!referenceTuple.Navigation.IsDependentToPrincipal() && isPrimaryKeySet)
                {
                    foreach (var fk in referenceTuple.Navigation.ForeignKey.Properties)
                    {
                        (referenceTuple.JProperty.Value as JObject)[fk.Name] = new JValue(fk.FindFirstPrincipal().AsProperty().Getter.GetClrValue(Entity));
                    }
                }
                if (referencedEntityMutationInfo == null)
                {
                    References[referenceTuple.Navigation].TargetEntityMutationInfo = referencedEntityMutationInfo = new EntityMutationInfo(referenceTuple.Navigation.GetTargetType(), (JObject)referenceTuple.JProperty.Value, MutationContext);
                    referencedEntityMutationInfo.Root = State == EntityState.Added;
                }
                References[referenceTuple.Navigation].IsModified = true;
                References[referenceTuple.Navigation].IsTouched  = true;
                referenceTuple.Navigation.AsNavigation().Setter.SetClrValue(Entity, References[referenceTuple.Navigation].TargetEntityMutationInfo.Entity);
                foreach (var foreignKeyProperty in referenceTuple.Navigation.ForeignKey.Properties)
                {
                    var isDependentToPrincipal      = referenceTuple.Navigation.IsDependentToPrincipal();
                    var fixedForeignKeyProperty     = isDependentToPrincipal ? foreignKeyProperty : foreignKeyProperty.FindFirstPrincipal();
                    var principalForeignKeyProperty = isDependentToPrincipal ? foreignKeyProperty.FindFirstPrincipal() : foreignKeyProperty;
                    if (!Properties[fixedForeignKeyProperty].IsTouched)
                    {
                        Properties[fixedForeignKeyProperty].IsTouched  = true;
                        Properties[fixedForeignKeyProperty].IsModified = true;
                        fixedForeignKeyProperty.AsProperty().Setter.SetClrValue(Entity, principalForeignKeyProperty.AsProperty().Getter.GetClrValue(referencedEntityMutationInfo.Entity));
                    }
                }
                var inverseNavigation = referenceTuple.Navigation.FindInverse();
                if (inverseNavigation != null)
                {
                    if (inverseNavigation.IsCollection())
                    {
                        var inverseReferenceMutationInfo = referencedEntityMutationInfo.Collections[inverseNavigation];
                        inverseReferenceMutationInfo.TargetEntityMutationInfos.Add(this);
                        inverseReferenceMutationInfo.IsModified = true;
                        inverseReferenceMutationInfo.IsTouched  = true;
                        inverseNavigation.AsNavigation().CollectionAccessor.Add(referencedEntityMutationInfo.Entity, Entity, false);
                    }
                    else
                    {
                        var inverseReferenceMutationInfo = referencedEntityMutationInfo.References[inverseNavigation];
                        inverseReferenceMutationInfo.TargetEntityMutationInfo = this;
                        inverseReferenceMutationInfo.IsModified = true;
                        inverseReferenceMutationInfo.IsTouched  = true;
                        inverseNavigation.AsNavigation().Setter.SetClrValue(referencedEntityMutationInfo.Entity, Entity);
                    }
                }
            }
            foreach (var collectionTuple in CollectionTuples)
            {
                var targetEntityMutationInfos = collectionTuple.JProperty.Values().Select(value => new EntityMutationInfo(collectionTuple.Navigation.GetTargetType(), (JObject)value, MutationContext)).ToHashSet();
                Collections[collectionTuple.Navigation].IsModified = true;
                Collections[collectionTuple.Navigation].IsTouched  = true;
                var foreignKeyProperties = collectionTuple.Navigation.ForeignKey.Properties;
                foreach (var targetEntityMutationInfo in targetEntityMutationInfos)
                {
                    Collections[collectionTuple.Navigation].TargetEntityMutationInfos.Add(targetEntityMutationInfo);
                    foreach (var foreignKeyProperty in foreignKeyProperties)
                    {
                        var referenceKeyProperty           = foreignKeyProperty.FindFirstPrincipal();
                        var foreignKeyPropertyMutationInfo = targetEntityMutationInfo.Properties[foreignKeyProperty];
                        foreignKeyPropertyMutationInfo.IsModified = true;
                        foreignKeyPropertyMutationInfo.IsTouched  = true;
                        foreignKeyProperty.AsProperty().Setter.SetClrValue(targetEntityMutationInfo.Entity, referenceKeyProperty.AsProperty().Getter.GetClrValue(Entity));
                    }
                    var inverseNavigation = collectionTuple.Navigation.FindInverse();
                    if (inverseNavigation != null)
                    {
                        var inverseReferenceMutationInfo = targetEntityMutationInfo.References[inverseNavigation];
                        inverseReferenceMutationInfo.IsModified = true;
                        inverseReferenceMutationInfo.IsTouched  = true;
                        inverseReferenceMutationInfo.TargetEntityMutationInfo = this;
                        inverseNavigation.AsNavigation().Setter.SetClrValue(targetEntityMutationInfo.Entity, Entity);
                    }
                    collectionTuple.Navigation.AsNavigation().CollectionAccessor.Add(Entity, targetEntityMutationInfo.Entity, false);
                }
            }
        }
Пример #6
0
 public CollectionMutationInfo(MutationContext mutationContext, INavigation navigation, EntityMutationInfo entityMutationInfo) : base(mutationContext, navigation, entityMutationInfo)
 {
     TargetEntityMutationInfos = new HashSet <EntityMutationInfo>();
 }