diff --git a/Source/Tests/TrackableEntities.EF.5.Tests/NorthwindDbContextTests.cs b/Source/Tests/TrackableEntities.EF.5.Tests/NorthwindDbContextTests.cs index 8940a409..24d4aa34 100644 --- a/Source/Tests/TrackableEntities.EF.5.Tests/NorthwindDbContextTests.cs +++ b/Source/Tests/TrackableEntities.EF.5.Tests/NorthwindDbContextTests.cs @@ -399,6 +399,27 @@ public void Apply_Changes_Should_Mark_Order_Modified_With_OrderDetails_Added_Mod Assert.AreEqual(EntityState.Modified, context.Entry(detail2).State); Assert.AreEqual(EntityState.Deleted, context.Entry(detail3).State); Assert.AreEqual(EntityState.Unchanged, context.Entry(detail4).State); + Assert.AreEqual(EntityState.Unchanged, context.Entry(detail1.Product).State); + } + + [Test] + public void Apply_Changes_Should_Mark_Unchanged_Product_Of_Added_OrderDetail_Of_Added_Order_As_Unchanged() + { + // Arrange + var context = TestsHelper.CreateNorthwindDbContext(CreateNorthwindDbOptions); + var order = new MockNorthwind().Orders[0]; + var orderDetail = order.OrderDetails[0]; + var product = orderDetail.Product; + order.TrackingState = TrackingState.Added; + orderDetail.TrackingState = TrackingState.Added; + + // Act + context.ApplyChanges(order); + + // Assert + Assert.AreEqual(EntityState.Added, context.Entry(order).State); + Assert.AreEqual(EntityState.Added, context.Entry(orderDetail).State); + Assert.AreEqual(EntityState.Unchanged, context.Entry(product).State); } [Test] diff --git a/Source/TrackableEntities.EF.5/DbContextExtensions.cs b/Source/TrackableEntities.EF.5/DbContextExtensions.cs index 2154a50d..4ad43fc0 100644 --- a/Source/TrackableEntities.EF.5/DbContextExtensions.cs +++ b/Source/TrackableEntities.EF.5/DbContextExtensions.cs @@ -97,13 +97,11 @@ private static void ApplyChanges(this DbContext context, // Set state for child collections context.ApplyChangesOnProperties(item, visitationHelper); return; - } + } - // Exit if parent is added or deleted, - // and it's not a M-1 relation + // Exit if parent is deleted and not a M-1 relation if (parent != null - && (parent.TrackingState == TrackingState.Added - || parent.TrackingState == TrackingState.Deleted) + && (parent.TrackingState == TrackingState.Deleted) && !context.IsRelatedProperty(parent.GetType(), propertyName, RelationshipType.ManyToOne)) return; @@ -126,9 +124,14 @@ private static void ApplyChanges(this DbContext context, return; } - // Set state to Added on parent only + // Set state to Added if item marked as Added if (item.TrackingState == TrackingState.Added - && (state == null || state == TrackingState.Added)) + && (state == null || state == TrackingState.Added) + // Or if parent marked as Added and 1-M or 1-1 relation + || (parent != null + && parent.TrackingState == TrackingState.Added + && (context.IsRelatedProperty(parent.GetType(), propertyName, RelationshipType.OneToMany) + || context.IsRelatedProperty(parent.GetType(), propertyName, RelationshipType.OneToOne)))) { context.Entry(item).State = EntityState.Added; context.ApplyChangesOnProperties(item, visitationHelper); @@ -565,6 +568,9 @@ private static bool IsRelatedProperty(this DbContext dbContext, case RelationshipType.ManyToMany: return navProp.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many && navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many; + case RelationshipType.OneToMany: + return navProp.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.One + && navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many; default: return false; } @@ -603,6 +609,7 @@ enum RelationshipType ManyToOne, OneToOne, ManyToMany, + OneToMany } #endregion