private static void RemoveDenormalizedInstances(
            IStateManager stateManager,
            INavigation navigation,
            object entity,
            object instance)
        {
            InternalEntityEntry internalEntityEntry = stateManager.TryGetEntry(entity);

            internalEntityEntry.EnsureRelationshipSnapshot();

            INavigation inverse            = navigation.FindInverse();
            IKey        primaryKey         = inverse.DeclaringEntityType.FindPrimaryKey();
            IProperty   primaryKeyProperty = primaryKey.Properties.Single();
            object      keyValue           = primaryKeyProperty.GetGetter().GetClrValue(instance);

            IClrCollectionAccessor collectionAccessor = navigation.GetCollectionAccessor();
            ICollection            list = (ICollection)collectionAccessor.GetOrCreate(entity);

            IList <object> toRemove = list
                                      .OfType <object>()
                                      .Where(item => (Equals(
                                                          keyValue,
                                                          primaryKeyProperty.GetGetter().GetClrValue(item)) &&
                                                      !ReferenceEquals(instance, item)))
                                      .ToList();

            foreach (object item in toRemove)
            {
                collectionAccessor.Remove(entity, item);
                internalEntityEntry.RemoveFromCollectionSnapshot(navigation, item);
            }
        }
Exemplo n.º 2
0
            private static TCollection PopulateCollection <TEntity, TCollection>(
                IClrCollectionAccessor accessor,
                IEnumerable <TEntity> entities)
            {
                // TODO: throw a better exception for non ICollection navigations
                var collection = (ICollection <TEntity>)accessor.Create();

                foreach (var entity in entities)
                {
                    collection.Add(entity);
                }

                return((TCollection)collection);
            }
Exemplo n.º 3
0
 private void SetReferenceOrAddToCollection(
     InternalEntityEntry entry,
     INavigation navigation,
     IClrCollectionAccessor collectionAccessor,
     object value)
 {
     if (collectionAccessor != null)
     {
         AddToCollection(entry, navigation, collectionAccessor, value);
     }
     else
     {
         SetNavigation(entry, navigation, value);
     }
 }
Exemplo n.º 4
0
 private void RemoveFromCollection(
     InternalEntityEntry entry,
     INavigation navigation,
     IClrCollectionAccessor collectionAccessor,
     object value)
 {
     _changeDetector.Suspend();
     try
     {
         collectionAccessor.Remove(entry.Entity, value);
     }
     finally
     {
         _changeDetector.Resume();
     }
     entry.RemoveFromCollectionSnapshot(navigation, value);
 }
Exemplo n.º 5
0
            private static TCollection MaterializeCollection <TElement, TCollection>(
                QueryContext queryContext,
                IEnumerable <ValueBuffer> innerValueBuffers,
                Func <QueryContext, ValueBuffer, TElement> innerShaper,
                IClrCollectionAccessor clrCollectionAccessor)
                where TCollection : class, ICollection <TElement>
            {
                var collection = (TCollection)(clrCollectionAccessor?.Create() ?? new List <TElement>());

                foreach (var valueBuffer in innerValueBuffers)
                {
                    var element = innerShaper(queryContext, valueBuffer);
                    collection.Add(element);
                }

                return(collection);
            }
            private static void InitializeCollectionInclude <TEntity, TIncludingEntity>(
                int collectionId,
                QueryContext queryContext,
                DbDataReader dbDataReader,
                ResultCoordinator resultCoordinator,
                TEntity entity,
                Func <QueryContext, DbDataReader, object[]> outerIdentifier,
                INavigation navigation,
                IClrCollectionAccessor clrCollectionAccessor,
                bool trackingQuery)
                where TIncludingEntity : TEntity
            {
                object collection = null;

                if (entity is TIncludingEntity)
                {
                    // Include case
                    if (trackingQuery)
                    {
                        queryContext.StateManager.TryGetEntry(entity).SetIsLoaded(navigation);
                    }
                    else
                    {
                        SetIsLoadedNoTracking(entity, navigation);
                    }

                    collection = clrCollectionAccessor.GetOrCreate(entity);
                }

                var outerKey = outerIdentifier(queryContext, dbDataReader);

                var collectionMaterializationContext = new CollectionMaterializationContext(entity, collection, outerKey);

                if (resultCoordinator.Collections.Count == collectionId)
                {
                    resultCoordinator.Collections.Add(collectionMaterializationContext);
                }
                else
                {
                    resultCoordinator.Collections[collectionId] = collectionMaterializationContext;
                }
            }
            private static TCollection InitializeCollection <TElement, TCollection>(
                int collectionId,
                QueryContext queryContext,
                DbDataReader dbDataReader,
                ResultCoordinator resultCoordinator,
                Func <QueryContext, DbDataReader, object[]> parentIdentifier,
                Func <QueryContext, DbDataReader, object[]> outerIdentifier,
                IClrCollectionAccessor clrCollectionAccessor)
                where TCollection : class, IEnumerable <TElement>
            {
                var collection = clrCollectionAccessor?.Create() ?? new List <TElement>();

                var parentKey = parentIdentifier(queryContext, dbDataReader);
                var outerKey  = outerIdentifier(queryContext, dbDataReader);

                var collectionMaterializationContext = new CollectionMaterializationContext(null, collection, parentKey, outerKey);

                resultCoordinator.SetCollectionMaterializationContext(collectionId, collectionMaterializationContext);

                return((TCollection)collection);
            }
Exemplo n.º 8
0
        /// <inheritdoc />
        public override void IncludeCollection <TEntity, TRelated, TElement>(
            int includeId,
            INavigation navigation,
            INavigation inverseNavigation,
            IEntityType targetEntityType,
            IClrCollectionAccessor clrCollectionAccessor,
            IClrPropertySetter inverseClrPropertySetter,
            bool tracking,
            TEntity entity,
            Func <IEnumerable <TRelated> > relatedEntitiesFactory,
            Func <TEntity, TRelated, bool> joinPredicate)
        {
            Check.NotNull(clrCollectionAccessor, nameof(clrCollectionAccessor));
            Check.NotNull(inverseNavigation, nameof(inverseNavigation));
            Check.NotNull(inverseClrPropertySetter, nameof(inverseClrPropertySetter));

            ICollection <TRelated> collection = (ICollection <TRelated>)clrCollectionAccessor
                                                .GetOrCreate(entity);

            IClrPropertyGetter primaryKeyPropertyGetter = inverseNavigation
                                                          .DeclaringEntityType
                                                          .FindPrimaryKey()
                                                          .Properties
                                                          .Single()
                                                          .GetGetter();

            IEnumerable <(TRelated, TRelated)> relatedEntities = relatedEntitiesFactory()
                                                                 .Join(collection,
                                                                       related => primaryKeyPropertyGetter.GetClrValue(related),
                                                                       related => primaryKeyPropertyGetter.GetClrValue(related),
                                                                       (related, original) => (related, original))
                                                                 .ToList();

            foreach ((TRelated related, TRelated original) in relatedEntities)
            {
                collection.Remove(original);
                collection.Add(related);
                inverseClrPropertySetter.SetClrValue(related, entity);
            }
        }
Exemplo n.º 9
0
 private void AddToCollection(
     InternalEntityEntry entry,
     INavigation navigation,
     IClrCollectionAccessor collectionAccessor,
     object value)
 {
     if (navigation != null)
     {
         _changeDetector.Suspend();
         try
         {
             if (collectionAccessor.Add(entry.Entity, value))
             {
                 entry.AddToCollectionSnapshot(navigation, value);
             }
         }
         finally
         {
             _changeDetector.Resume();
         }
     }
 }
            private static void InitializeIncludeCollection <TParent, TNavigationEntity>(
                int collectionId,
                QueryContext queryContext,
                DbDataReader dbDataReader,
                ResultCoordinator resultCoordinator,
                TParent entity,
                Func <QueryContext, DbDataReader, object[]> parentIdentifier,
                Func <QueryContext, DbDataReader, object[]> outerIdentifier,
                INavigation navigation,
                IClrCollectionAccessor clrCollectionAccessor,
                bool trackingQuery)
                where TNavigationEntity : TParent
            {
                object collection = null;

                if (entity is TNavigationEntity)
                {
                    if (trackingQuery)
                    {
                        queryContext.SetNavigationIsLoaded(entity, navigation);
                    }
                    else
                    {
                        SetIsLoadedNoTracking(entity, navigation);
                    }

                    collection = clrCollectionAccessor.GetOrCreate(entity, forMaterialization: true);
                }

                var parentKey = parentIdentifier(queryContext, dbDataReader);
                var outerKey  = outerIdentifier(queryContext, dbDataReader);

                var collectionMaterializationContext = new CollectionMaterializationContext(entity, collection, parentKey, outerKey);

                resultCoordinator.SetCollectionMaterializationContext(collectionId, collectionMaterializationContext);
            }
        public object CreateSecurityObject(IModel model, ISecurityObjectRepository securityObjectRepository)
        {
            Type targetType = RealObject.GetType();

            SecurityObject = Activator.CreateInstance(RealObject.GetType());
            IEntityType entityType = model.FindEntityType(targetType);
            IEnumerable <PropertyInfo> propertiesInfo = targetType.GetRuntimeProperties();
            IEnumerable <INavigation>  navigations    = entityType.GetNavigations();

            foreach (PropertyInfo propertyInfo in propertiesInfo)
            {
                object defaultValue = propertyInfo.GetValue(SecurityObject);
                defaultValueDictionary[propertyInfo.Name] = defaultValue;
                if (this.IsPropertyBlocked(propertyInfo.Name))
                {
                    if (navigations.Any(p => p.Name == propertyInfo.Name))
                    {
                        INavigation navigation = navigations.First(p => p.Name == propertyInfo.Name);
                        if (navigation.IsCollection())
                        {
                            if (propertyInfo.SetMethod != null)
                            {
                                propertyInfo.SetValue(SecurityObject, null);
                            }
                        }
                    }
                    continue;
                }
                if (navigations.Any(p => p.Name == propertyInfo.Name))
                {
                    INavigation navigation = navigations.First(p => p.Name == propertyInfo.Name);
                    if (navigation.IsCollection())
                    {
                        IClrCollectionAccessor collectionAccessor         = navigation.GetCollectionAccessor();
                        IEnumerable            objectRealListProperty     = (IEnumerable)propertyInfo.GetValue(RealObject);
                        IEnumerable            objectSecurityListProperty = (IEnumerable)propertyInfo.GetValue(SecurityObject);
                        List <object>          denyObject;
                        BlockedObjectsInListProperty.TryGetValue(propertyInfo.Name, out denyObject);
                        if (objectRealListProperty != null)
                        {
                            foreach (object objInList in objectRealListProperty)
                            {
                                if (denyObject != null && denyObject.Contains(objInList))
                                {
                                    continue;
                                }
                                object objectToAdd;
                                SecurityObjectBuilder metadata = securityObjectRepository.GetObjectMetaData(objInList);
                                if (metadata != null)
                                {
                                    if (metadata.SecurityObject != null)
                                    {
                                        objectToAdd = metadata.SecurityObject;
                                    }
                                    else
                                    {
                                        objectToAdd = metadata.CreateSecurityObject(model, securityObjectRepository);
                                    }
                                }
                                else
                                {
                                    throw new Exception();
                                }
                                collectionAccessor.Add(SecurityObject, objectToAdd);
                            }
                        }
                    }
                    else
                    {
                        object realValue = propertyInfo.GetValue(RealObject);
                        SecurityObjectBuilder metadata = securityObjectRepository.GetObjectMetaData(realValue);
                        if (metadata != null && realValue != null)
                        {
                            if (metadata.SecurityObject == null)
                            {
                                metadata.SecurityObject = metadata.CreateSecurityObject(model, securityObjectRepository);
                            }
                            if (propertyInfo.SetMethod != null)
                            {
                                propertyInfo.SetValue(SecurityObject, metadata.SecurityObject);
                            }
                        }
                        else
                        {
                            if (propertyInfo.SetMethod != null)
                            {
                                propertyInfo.SetValue(SecurityObject, realValue);
                            }
                        }
                    }
                }
                else
                {
                    if (propertyInfo.SetMethod != null)
                    {
                        object realValue = propertyInfo.GetValue(RealObject);
                        propertyInfo.SetValue(SecurityObject, realValue);
                    }
                }
            }
            foreach (PropertyInfo propertyInfo in propertiesInfo)
            {
                object originalValue = propertyInfo.GetValue(SecurityObject);
                originalValueSecurityObjectDictionary.Add(propertyInfo.Name, originalValue);
            }

            if (SecurityObject is ISecurityEntity)
            {
                ISecurityEntity securityEntity = (ISecurityEntity)SecurityObject;

                List <string> blockedMembers = new List <string>();
                blockedMembers.AddRange(BlockedProperties);
                blockedMembers.AddRange(BlockedNavigationProperties);

                securityEntity.BlockedMembers = blockedMembers;
            }

            return(SecurityObject);
        }
Exemplo n.º 12
0
 private void SetReferenceOrAddToCollection(
     InternalEntityEntry entry,
     INavigation navigation,
     IClrCollectionAccessor collectionAccessor,
     object value)
 {
     if (collectionAccessor != null)
     {
         AddToCollection(entry, navigation, collectionAccessor, value);
     }
     else
     {
         SetNavigation(entry, navigation, value);
     }
 }
Exemplo n.º 13
0
        private void InitialFixup(StateEntry entry, EntityState oldState)
        {
            var entityType = entry.EntityType;

            foreach (var navigation in entityType.Navigations)
            {
                var navigationValue = entry[navigation];

                if (navigationValue != null)
                {
                    if (navigation.IsCollection())
                    {
                        NavigationCollectionChangedAction(
                            entry,
                            navigation,
                            ((IEnumerable)navigationValue).Cast <object>().ToList(),
                            Enumerable.Empty <object>());
                    }
                    else
                    {
                        NavigationReferenceChangedAction(
                            entry,
                            navigation,
                            null,
                            navigationValue);
                    }
                }
            }

            var stateEntries = entry.StateManager.StateEntries.ToList();

            // TODO: Perf on this state manager query
            foreach (var navigation in _model.Service.EntityTypes
                     .SelectMany(e => e.Navigations)
                     .Where(n => n.GetTargetType() == entityType))
            {
                IClrCollectionAccessor collectionAccessor = null;
                if (navigation.IsCollection())
                {
                    collectionAccessor = _collectionAccessorSource.GetAccessor(navigation);
                }

                var navigationEntityType = navigation.EntityType;

                foreach (var relatedEntry in stateEntries)
                {
                    if (relatedEntry.EntityType != navigationEntityType ||
                        relatedEntry == entry)
                    {
                        continue;
                    }

                    if (collectionAccessor != null)
                    {
                        if (collectionAccessor.Contains(relatedEntry.Entity, entry.Entity))
                        {
                            NavigationCollectionChangedAction(
                                relatedEntry,
                                navigation,
                                new[] { entry.Entity },
                                Enumerable.Empty <object>());
                        }
                    }
                    else
                    {
                        var navigationValue = relatedEntry[navigation];

                        if (navigationValue != null)
                        {
                            if (ReferenceEquals(navigationValue, entry.Entity))
                            {
                                NavigationReferenceChangedAction(
                                    relatedEntry,
                                    navigation,
                                    null,
                                    navigationValue);
                            }
                        }
                    }
                }
            }

            foreach (var foreignKey in entityType.ForeignKeys)
            {
                var principalEntry = entry.StateManager.GetPrincipal(entry.RelationshipsSnapshot, foreignKey);
                if (principalEntry != null)
                {
                    DoFixup(foreignKey, principalEntry, new[] { entry });
                }
            }

            foreach (var foreignKey in _model.Service.GetReferencingForeignKeys(entityType))
            {
                var dependents = entry.StateManager.GetDependents(entry, foreignKey).ToArray();

                if (dependents.Length > 0)
                {
                    DoFixup(foreignKey, entry, dependents);
                }
            }
        }
Exemplo n.º 14
0
        /// <inheritdoc />
        public override void IncludeCollection <TEntity, TRelated, TElement>(
            int includeId,
            INavigation navigation,
            INavigation inverseNavigation,
            IEntityType targetEntityType,
            IClrCollectionAccessor clrCollectionAccessor,
            IClrPropertySetter inverseClrPropertySetter,
            bool tracking,
            TEntity entity,
            Func <IEnumerable <TRelated> > relatedEntitiesFactory,
            Func <TEntity, TRelated, bool> joinPredicate)
        {
            Check.NotNull(clrCollectionAccessor, nameof(clrCollectionAccessor));
            Check.NotNull(inverseNavigation, nameof(inverseNavigation));
            Check.NotNull(inverseClrPropertySetter, nameof(inverseClrPropertySetter));

            ICollection <TRelated> collection = (ICollection <TRelated>)clrCollectionAccessor
                                                .GetOrCreate(entity);

            IClrPropertyGetter primaryKeyPropertyGetter = navigation
                                                          .GetTargetType()
                                                          .FindPrimaryKey()
                                                          .Properties
                                                          .Single()
                                                          .GetGetter();

            IDictionary <object, TRelated> replacementMap = relatedEntitiesFactory()
                                                            .ToDictionary(
                related => primaryKeyPropertyGetter.GetClrValue(related));

            IEnumerable <object> newCollectionItems = collection
                                                      .Select(original =>
                                                              replacementMap.TryGetValue(
                                                                  primaryKeyPropertyGetter.GetClrValue(original),
                                                                  out TRelated related)
                        ? related
                        : original)
                                                      .Cast <object>()
                                                      .ToList();

            collection.Clear();

            foreach (TRelated item in newCollectionItems)
            {
                inverseClrPropertySetter.SetClrValue(item, entity);

                if (tracking)
                {
                    InternalEntityEntry originalEntry = _stateManager.TryGetEntry(item);
                    if (originalEntry != null)
                    {
                        _stateManager.StopTracking(originalEntry);
                    }

                    base.StartTracking(
                        LoadEntity(
                            item,
                            targetEntityType,
                            entity,
                            inverseNavigation),
                        targetEntityType);
                }
            }
        }
Exemplo n.º 15
0
        private void InitialFixup(InternalEntityEntry entry)
        {
            var entityType = entry.EntityType;

            // If the new state is unchanged (such as from a query or Attach) then we are going
            // to assume that the FK value is the source of truth and not attempt to ascertain
            // relationships from navigation properties
            if (entry.EntityState != EntityState.Unchanged)
            {
                foreach (var navigation in entityType.GetNavigations())
                {
                    var navigationValue = entry[navigation];
                    if (navigationValue != null)
                    {
                        if (navigation.IsCollection())
                        {
                            NavigationCollectionChangedAction(
                                entry,
                                navigation,
                                ((IEnumerable)navigationValue).Cast <object>().ToList(),
                                Enumerable.Empty <object>());
                        }
                        else
                        {
                            NavigationReferenceChangedAction(
                                entry,
                                navigation,
                                null,
                                navigationValue);
                        }
                    }
                }

                var entries = entry.StateManager.Entries.ToList();

                // TODO: Perf on this state manager query
                foreach (var navigation in _model.EntityTypes
                         .SelectMany(e => e.GetNavigations())
                         .Where(n => n.GetTargetType().IsAssignableFrom(entityType)))
                {
                    IClrCollectionAccessor collectionAccessor = null;
                    if (navigation.IsCollection())
                    {
                        collectionAccessor = _collectionAccessorSource.GetAccessor(navigation);
                    }

                    var navigationEntityType = navigation.DeclaringEntityType;

                    foreach (var relatedEntry in entries)
                    {
                        if (!navigationEntityType.IsAssignableFrom(relatedEntry.EntityType) ||
                            relatedEntry == entry)
                        {
                            continue;
                        }

                        if (collectionAccessor != null)
                        {
                            if (collectionAccessor.Contains(relatedEntry.Entity, entry.Entity))
                            {
                                NavigationCollectionChangedAction(
                                    relatedEntry,
                                    navigation,
                                    new[] { entry.Entity },
                                    Enumerable.Empty <object>());
                            }
                        }
                        else
                        {
                            var navigationValue = relatedEntry[navigation];
                            if (navigationValue != null)
                            {
                                if (ReferenceEquals(navigationValue, entry.Entity))
                                {
                                    NavigationReferenceChangedAction(
                                        relatedEntry,
                                        navigation,
                                        null,
                                        navigationValue);
                                }
                            }
                        }
                    }
                }
            }

            foreach (var foreignKey in entityType.GetForeignKeys())
            {
                var principalEntry = entry.StateManager.GetPrincipal(entry.RelationshipsSnapshot, foreignKey);
                if (principalEntry != null)
                {
                    DoFixup(foreignKey, principalEntry, new[] { entry });
                }
            }

            foreach (var foreignKey in _model.FindReferencingForeignKeys(entityType))
            {
                var dependents = entry.StateManager.GetDependents(entry, foreignKey).ToArray();
                if (dependents.Length > 0)
                {
                    DoFixup(foreignKey, entry, dependents);
                }
            }
        }
Exemplo n.º 16
0
 private void RemoveFromCollection(
     InternalEntityEntry entry,
     INavigation navigation,
     IClrCollectionAccessor collectionAccessor,
     object value)
 {
     _changeDetector.Suspend();
     try
     {
         collectionAccessor.Remove(entry.Entity, value);
     }
     finally
     {
         _changeDetector.Resume();
     }
     entry.RemoveFromCollectionSnapshot(navigation, value);
 }
Exemplo n.º 17
0
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public virtual async Task IncludeCollectionAsync(
            int includeId,
            INavigation navigation,
            INavigation inverseNavigation,
            IEntityType targetEntityType,
            IClrCollectionAccessor clrCollectionAccessor,
            IClrPropertySetter inverseClrPropertySetter,
            bool tracking,
            object entity,
            Func <IAsyncEnumerable <object> > relatedEntitiesFactory,
            CancellationToken cancellationToken)
        {
            IDisposable untypedAsyncEnumerator        = null;
            IAsyncEnumerator <object> asyncEnumerator = null;

            if (includeId == -1 ||
                !_includedCollections.TryGetValue(includeId, out untypedAsyncEnumerator))
            {
                asyncEnumerator = relatedEntitiesFactory().GetEnumerator();

                if (!await asyncEnumerator.MoveNext(cancellationToken))
                {
                    asyncEnumerator.Dispose();
                    asyncEnumerator = null;
                }

                if (includeId != -1)
                {
                    _includedCollections.Add(includeId, asyncEnumerator);
                }
            }

            if (asyncEnumerator == null)
            {
                if (untypedAsyncEnumerator == null)
                {
                    clrCollectionAccessor.GetOrCreate(entity);

                    return;
                }

                asyncEnumerator = (IAsyncEnumerator <object>)untypedAsyncEnumerator;
            }

            var relatedEntities = new List <object>();

            // TODO: This should be done at query compile time and not require a VB unless there are shadow props
            var keyComparer = CreateIncludeKeyComparer(entity, navigation);

            while (true)
            {
                bool shouldInclude;

                if (_valueBuffers.TryGetValue(asyncEnumerator.Current, out var relatedValueBuffer))
                {
                    shouldInclude = keyComparer.ShouldInclude((ValueBuffer)relatedValueBuffer);
                }
                else
                {
                    var entry = _dependencies.StateManager.TryGetEntry(asyncEnumerator.Current);

                    Debug.Assert(entry != null);

                    shouldInclude = keyComparer.ShouldInclude(entry);
                }

                if (shouldInclude)
                {
                    relatedEntities.Add(asyncEnumerator.Current);

                    if (tracking)
                    {
                        StartTracking(asyncEnumerator.Current, targetEntityType);
                    }

                    if (inverseNavigation != null)
                    {
                        Debug.Assert(inverseClrPropertySetter != null);

                        inverseClrPropertySetter.SetClrValue(asyncEnumerator.Current, entity);

                        if (tracking)
                        {
                            var internalEntityEntry = _dependencies.StateManager.TryGetEntry(asyncEnumerator.Current);

                            Debug.Assert(internalEntityEntry != null);

                            internalEntityEntry.SetRelationshipSnapshotValue(inverseNavigation, entity);
                        }
                    }

                    if (!await asyncEnumerator.MoveNext(cancellationToken))
                    {
                        asyncEnumerator.Dispose();

                        _includedCollections[includeId] = null;

                        break;
                    }
                }
                else
                {
                    break;
                }
            }

            clrCollectionAccessor.AddRange(entity, relatedEntities);

            if (tracking)
            {
                var internalEntityEntry = _dependencies.StateManager.TryGetEntry(entity);

                Debug.Assert(internalEntityEntry != null);

                internalEntityEntry.AddRangeToCollectionSnapshot(navigation, relatedEntities);
                internalEntityEntry.SetIsLoaded(navigation);
            }
        }
        public object CreateRealObject(IModel model, ISecurityObjectRepository securityObjectRepository)
        {
            Type targetType = SecurityObject.GetType();

            RealObject = Activator.CreateInstance(SecurityObject.GetType());
            IEntityType entityType = model.FindEntityType(targetType);
            IEnumerable <PropertyInfo> properiesInfo = targetType.GetRuntimeProperties();
            IEnumerable <INavigation>  navigations   = entityType.GetNavigations();

            IReadOnlyList <IProperty> primaryKeyProperties = entityType.FindPrimaryKey().Properties;

            foreach (PropertyInfo propertyInfo in properiesInfo)
            {
                object defaultValue = propertyInfo.GetValue(RealObject);
                defaultValueDictionary[propertyInfo.Name] = defaultValue;
                if (navigations.Any(p => p.Name == propertyInfo.Name))
                {
                    INavigation navigation = navigations.First(p => p.Name == propertyInfo.Name);
                    if (navigation.IsCollection())
                    {
                        IClrCollectionAccessor collectionAccessor              = navigation.GetCollectionAccessor();
                        IEnumerable            realObjectListPropertyValue     = (IEnumerable)propertyInfo.GetValue(RealObject);
                        IEnumerable            securityObjectListPropertyValue = (IEnumerable)propertyInfo.GetValue(SecurityObject);
                        if (securityObjectListPropertyValue != null && realObjectListPropertyValue != null)
                        {
                            foreach (object objectInListProperty in securityObjectListPropertyValue)
                            {
                                SecurityObjectBuilder metadata = securityObjectRepository.GetObjectMetaData(objectInListProperty);
                                if (metadata == null)
                                {
                                    metadata = new SecurityObjectBuilder();
                                    securityObjectRepository.RegisterBuilder(metadata);
                                    metadata.SecurityObject = objectInListProperty;
                                    metadata.CreateRealObject(model, securityObjectRepository);
                                }
                                collectionAccessor.Add(RealObject, metadata.RealObject);
                            }
                        }
                    }
                    else
                    {
                        object realValue = propertyInfo.GetValue(SecurityObject);
                        if (!Equals(realValue, null))
                        {
                            SecurityObjectBuilder metadata = securityObjectRepository.GetObjectMetaData(realValue);
                            if (metadata == null)
                            {
                                metadata = new SecurityObjectBuilder();
                                securityObjectRepository.RegisterBuilder(metadata);
                                metadata.SecurityObject = realValue;

                                metadata.CreateRealObject(model, securityObjectRepository);
                            }
                            if (propertyInfo.SetMethod != null)
                            {
                                propertyInfo.SetValue(RealObject, metadata.RealObject);
                            }
                        }
                    }
                }
                else
                {
                    bool isGeneratedPrimaryKey = false;
                    foreach (IProperty primaryKeyProperty in primaryKeyProperties)
                    {
                        if ((propertyInfo.Name == primaryKeyProperty.Name) && primaryKeyProperty.RequiresValueGenerator)
                        {
                            isGeneratedPrimaryKey = true;
                        }
                    }
                    if (propertyInfo.SetMethod != null && !isGeneratedPrimaryKey)
                    {
                        object securityValue = propertyInfo.GetValue(SecurityObject);
                        propertyInfo.SetValue(RealObject, securityValue);
                    }
                }
            }
            return(RealObject);
        }
Exemplo n.º 19
0
 private void AddToCollection(
     InternalEntityEntry entry,
     INavigation navigation,
     IClrCollectionAccessor collectionAccessor,
     object value)
 {
     if (navigation != null)
     {
         _changeDetector.Suspend();
         try
         {
             if (collectionAccessor.Add(entry.Entity, value))
             {
                 entry.AddToCollectionSnapshot(navigation, value);
             }
         }
         finally
         {
             _changeDetector.Resume();
         }
     }
 }