Пример #1
0
        /// <summary>
        /// Inserts or updates the specified domain entity and any entities within its graph. The calling client will need
        /// to set the appropriate state on the domain entities within the graph.
        /// </summary>
        /// <param name="entity">The entity.</param>
        public void InsertOrUpdateGraph(TEntity entity)
        {
            // Get a list of entities currently being tracked, as don't want to reprocess them in the code below
            IList <DbEntityEntry> trackedEntrys = this.DbContext.ChangeTracker.Entries().ToList();

            // Adding the entity will mark attach all entities in the graph to the dbContext. It will also ensure all FK relationships are set correctly.
            this.dbSet.Add(entity);

            var changedEntities = this.DbContext.ChangeTracker.Entries();

            // For any entities being tracked, tell the context about the entities state.
            foreach (DbEntityEntry entry in changedEntities)
            {
                if (trackedEntrys.Contains(entry))
                {
                    // This entry was already in the tracker before this method call, so ignore
                    continue;
                }

                if (entry.Entity is IEntityWithState)
                {
                    IEntityWithState entityWithState = (IEntityWithState)entry.Entity;

                    if (entityWithState.State == State.NotSet)
                    {
                        // If the entity states have not been set, then use a convention to determine then entity state based on whether
                        // the entity has an Id
                        entityWithState.State = CalculateEntityStateBasedOnConvention(entry.Entity);
                    }

                    // Convert the domain representation of state to the entity framework enumeration
                    entry.State = GetEntityState(entityWithState.State);
                }
            }

            if (this.unitOfWork != null && this.unitOfWork.Transaction != null)
            {
                this.DbContext.SaveChanges();
            }

            this.ClearCache();
        }
        public void InsertGraphForNewAggregateRootEntityAndChildrenWhereChildrenSpecifiedAsUnchanged()
        {
            // Arrange
            const int expectedSimpleId1 = 10;
            const int expectedSimpleId2 = 11;
            const int expectedSimpleId3 = 12;

            FakeDbContext dbContext = new FakeDbContext();
            AggregateRootEntityRepository entityRepository = new AggregateRootEntityRepository(dbContext);

            // Create an aggregate root where one of the 'AnotherSimpleEntity' already exist (i.e. has a primary key)
            AggregateRootEntity aggregateRootEntity = new AggregateRootEntity
            {
                SomeOtherProperty = "Some other property",
                SimpleEntity      = new SimpleEntity {
                    Id = expectedSimpleId1, SomeProperty = "Some property", State = State.Unchanged
                },
                OtherSimpleEntities = new List <AnotherSimpleEntity>
                {
                    new AnotherSimpleEntity {
                        Id = expectedSimpleId2, SomeProperty = "Child property 1", State = State.Unchanged
                    },
                    new AnotherSimpleEntity {
                        Id = expectedSimpleId3, SomeProperty = "Child property 2", State = State.Unchanged
                    },
                }
            };

            // Act
            entityRepository.InsertOrUpdateGraph(aggregateRootEntity);

            // Assert
            Assert.IsNotNull(entityRepository.DbContext);

            // The AggregateRoot and its children should all be added to the context and all have a state of 'Added'
            Assert.AreEqual(4, entityRepository.DbContext.ChangeTracker.Entries().Count());
            entityRepository.DbContext.ChangeTracker.Entries().ToList().ForEach(entry =>
            {
                IEntityWithState <int> entityWithState = (IEntityWithState <int>)entry.Entity;
                Assert.AreEqual(entityWithState.Id == default(int) ? EntityState.Added : EntityState.Unchanged, entry.State);
            });
        }