From bcf2afb7d148d1bdbc704e6788193184f35c5d68 Mon Sep 17 00:00:00 2001 From: ajcvickers Date: Mon, 7 Sep 2020 12:49:09 -0700 Subject: [PATCH] Automatically create notification collections when change-tracking proxies are being used Fixes #21684 --- .../Internal/ClrCollectionAccessorFactory.cs | 6 +- .../Internal/CollectionTypeFactory.cs | 8 +- .../ManyToManyLoadTestBase.cs | 30 +- .../ManyToManyTrackingTestBase.cs | 394 ++++++++++-------- .../ManyToManyModel/EntityBranch.cs | 3 +- .../ManyToManyModel/EntityCompositeKey.cs | 20 +- .../TestModels/ManyToManyModel/EntityLeaf.cs | 8 +- .../TestModels/ManyToManyModel/EntityOne.cs | 40 +- .../TestModels/ManyToManyModel/EntityRoot.cs | 7 +- .../TestModels/ManyToManyModel/EntityThree.cs | 29 +- .../TestModels/ManyToManyModel/EntityTwo.cs | 18 +- .../ManyToManyModel/ManyToManyContext.cs | 10 +- .../ManyToManyModel/ManyToManyData.cs | 93 ++++- .../Internal/CollectionTypeFactoryTest.cs | 47 ++- 14 files changed, 394 insertions(+), 319 deletions(-) diff --git a/src/EFCore/Metadata/Internal/ClrCollectionAccessorFactory.cs b/src/EFCore/Metadata/Internal/ClrCollectionAccessorFactory.cs index 1a92c6e15af..7e9c340d77c 100644 --- a/src/EFCore/Metadata/Internal/ClrCollectionAccessorFactory.cs +++ b/src/EFCore/Metadata/Internal/ClrCollectionAccessorFactory.cs @@ -153,7 +153,11 @@ private static IClrCollectionAccessor CreateGeneric); diff --git a/src/EFCore/Metadata/Internal/CollectionTypeFactory.cs b/src/EFCore/Metadata/Internal/CollectionTypeFactory.cs index 52f6d205e0f..135abe5d4a5 100644 --- a/src/EFCore/Metadata/Internal/CollectionTypeFactory.cs +++ b/src/EFCore/Metadata/Internal/CollectionTypeFactory.cs @@ -23,7 +23,10 @@ public class CollectionTypeFactory /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public virtual Type TryFindTypeToInstantiate([NotNull] Type entityType, [NotNull] Type collectionType) + public virtual Type TryFindTypeToInstantiate( + [NotNull] Type entityType, + [NotNull] Type collectionType, + bool requireFullNotifications) { // Code taken from EF6. The rules are: // If the collection is defined as a concrete type with a public parameterless constructor, then create an instance of that type @@ -48,7 +51,8 @@ public virtual Type TryFindTypeToInstantiate([NotNull] Type entityType, [NotNull } } - if (typeof(INotifyPropertyChanged).IsAssignableFrom(entityType)) + if (requireFullNotifications + || typeof(INotifyPropertyChanged).IsAssignableFrom(entityType)) { var observableHashSetOfT = typeof(ObservableHashSet<>).MakeGenericType(elementType); if (collectionType.IsAssignableFrom(observableHashSetOfT)) diff --git a/test/EFCore.Specification.Tests/ManyToManyLoadTestBase.cs b/test/EFCore.Specification.Tests/ManyToManyLoadTestBase.cs index 3409e5a41f9..17b1554f703 100644 --- a/test/EFCore.Specification.Tests/ManyToManyLoadTestBase.cs +++ b/test/EFCore.Specification.Tests/ManyToManyLoadTestBase.cs @@ -2,6 +2,8 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore.ChangeTracking; @@ -144,24 +146,24 @@ public virtual void Attached_collections_are_not_marked_as_loaded(EntityState st b => { b.Id = 7776; - b.TwoSkip.Add(new EntityTwo { Id = 7777 }); - b.TwoSkipShared.Add(new EntityTwo { Id = 7778 }); - b.SelfSkipPayloadLeft.Add(new EntityOne { Id = 7779 }); - b.SelfSkipPayloadRight.Add(new EntityOne { Id = 7780 }); - b.BranchSkip.Add(new EntityBranch { Id = 7781 }); - b.ThreeSkipPayloadFull.Add(new EntityThree { Id = 7782 }); - b.ThreeSkipPayloadFullShared.Add(new EntityThree { Id = 7783 }); + b.TwoSkip = new ObservableCollection { new EntityTwo { Id = 7777 } }; + b.TwoSkipShared = new ObservableCollection { new EntityTwo { Id = 7778 } }; + b.SelfSkipPayloadLeft = new ObservableCollection { new EntityOne { Id = 7779 } }; + b.SelfSkipPayloadRight = new ObservableCollection { new EntityOne { Id = 7780 } }; + b.BranchSkip = new ObservableCollection { new EntityBranch { Id = 7781 } }; + b.ThreeSkipPayloadFull = new ObservableCollection { new EntityThree { Id = 7782 } }; + b.ThreeSkipPayloadFullShared = new ObservableCollection { new EntityThree { Id = 7783 } }; }) : new EntityOne { Id = 7776, - TwoSkip = { new EntityTwo { Id = 7777 } }, - TwoSkipShared = { new EntityTwo { Id = 7778 } }, - SelfSkipPayloadLeft = { new EntityOne { Id = 7779 } }, - SelfSkipPayloadRight = { new EntityOne { Id = 7780 } }, - BranchSkip = { new EntityBranch { Id = 7781 } }, - ThreeSkipPayloadFull = { new EntityThree { Id = 7782 } }, - ThreeSkipPayloadFullShared = { new EntityThree { Id = 7783 } }, + TwoSkip = new List { new EntityTwo { Id = 7777 } }, + TwoSkipShared = new List { new EntityTwo { Id = 7778 } }, + SelfSkipPayloadLeft = new List { new EntityOne { Id = 7779 } }, + SelfSkipPayloadRight = new List { new EntityOne { Id = 7780 } }, + BranchSkip = new List { new EntityBranch { Id = 7781 } }, + ThreeSkipPayloadFull = new List { new EntityThree { Id = 7782 } }, + ThreeSkipPayloadFullShared = new List { new EntityThree { Id = 7783 } } }; context.Attach(left); diff --git a/test/EFCore.Specification.Tests/ManyToManyTrackingTestBase.cs b/test/EFCore.Specification.Tests/ManyToManyTrackingTestBase.cs index 7bbc9c7d200..c4a9f7222be 100644 --- a/test/EFCore.Specification.Tests/ManyToManyTrackingTestBase.cs +++ b/test/EFCore.Specification.Tests/ManyToManyTrackingTestBase.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Query; @@ -25,21 +26,21 @@ public virtual void Can_insert_many_to_many_composite_with_navs() var leftEntities = new[] { context.EntityCompositeKeys.CreateInstance( - e => + (e, p) => { e.Key1 = 7711; e.Key2 = "7711"; e.Key3 = new DateTime(7711, 1, 1); }), context.EntityCompositeKeys.CreateInstance( - e => + (e, p) => { e.Key1 = 7712; e.Key2 = "7712"; e.Key3 = new DateTime(7712, 1, 1); }), context.EntityCompositeKeys.CreateInstance( - e => + (e, p) => { e.Key1 = 7713; e.Key2 = "7713"; @@ -48,15 +49,19 @@ public virtual void Can_insert_many_to_many_composite_with_navs() }; var rightEntities = new[] { - context.Set().CreateInstance(e => e.Id = 7721), - context.Set().CreateInstance(e => e.Id = 7722), - context.Set().CreateInstance(e => e.Id = 7723) + context.Set().CreateInstance((e, p) => e.Id = 7721), + context.Set().CreateInstance((e, p) => e.Id = 7722), + context.Set().CreateInstance((e, p) => e.Id = 7723) }; + leftEntities[0].LeafSkipFull = CreateCollection(); + leftEntities[0].LeafSkipFull.Add(rightEntities[0]); // 11 - 21 leftEntities[0].LeafSkipFull.Add(rightEntities[1]); // 11 - 22 leftEntities[0].LeafSkipFull.Add(rightEntities[2]); // 11 - 23 + rightEntities[0].CompositeKeySkipFull = CreateCollection(); + rightEntities[0].CompositeKeySkipFull.Add(leftEntities[0]); // 21 - 11 (Dupe) rightEntities[0].CompositeKeySkipFull.Add(leftEntities[1]); // 21 - 12 rightEntities[0].CompositeKeySkipFull.Add(leftEntities[2]); // 21 - 13 @@ -121,13 +126,13 @@ public virtual void Can_update_many_to_many_composite_with_navs() var leftEntities = context.Set().Include(e => e.LeafSkipFull).OrderBy(e => e.Key1).ToList(); var rightEntities = context.Set().Include(e => e.CompositeKeySkipFull).ToList(); - leftEntities[0].LeafSkipFull.Add(context.Set().CreateInstance(e => e.Id = 7721)); - leftEntities[0].LeafSkipFull.Add(context.Set().CreateInstance(e => e.Id = 7722)); - leftEntities[0].LeafSkipFull.Add(context.Set().CreateInstance(e => e.Id = 7723)); + leftEntities[0].LeafSkipFull.Add(context.Set().CreateInstance((e, p) => e.Id = 7721)); + leftEntities[0].LeafSkipFull.Add(context.Set().CreateInstance((e, p) => e.Id = 7722)); + leftEntities[0].LeafSkipFull.Add(context.Set().CreateInstance((e, p) => e.Id = 7723)); rightEntities[0].CompositeKeySkipFull.Add( context.EntityCompositeKeys.CreateInstance( - e => + (e, p) => { e.Key1 = 7711; e.Key2 = "7711"; @@ -135,7 +140,7 @@ public virtual void Can_update_many_to_many_composite_with_navs() })); rightEntities[0].CompositeKeySkipFull.Add( context.EntityCompositeKeys.CreateInstance( - e => + (e, p) => { e.Key1 = 7712; e.Key2 = "7712"; @@ -143,7 +148,7 @@ public virtual void Can_update_many_to_many_composite_with_navs() })); rightEntities[0].CompositeKeySkipFull.Add( context.EntityCompositeKeys.CreateInstance( - e => + (e, p) => { e.Key1 = 7713; e.Key2 = "7713"; @@ -154,12 +159,12 @@ public virtual void Can_update_many_to_many_composite_with_navs() rightEntities[1].CompositeKeySkipFull.Remove(rightEntities[1].CompositeKeySkipFull.Single(e => e.Key2 == "3_1")); leftEntities[2].LeafSkipFull.Remove(leftEntities[2].LeafSkipFull.Single(e => e.Id == 23)); - leftEntities[2].LeafSkipFull.Add(context.Set().CreateInstance(e => e.Id = 7724)); + leftEntities[2].LeafSkipFull.Add(context.Set().CreateInstance((e, p) => e.Id = 7724)); rightEntities[2].CompositeKeySkipFull.Remove(rightEntities[2].CompositeKeySkipFull.Single(e => e.Key2 == "8_3")); rightEntities[2].CompositeKeySkipFull.Add( context.EntityCompositeKeys.CreateInstance( - e => + (e, p) => { e.Key1 = 7714; e.Key2 = "7714"; @@ -414,21 +419,21 @@ public virtual void Can_insert_many_to_many_composite_shared_with_navs() var leftEntities = new[] { context.EntityCompositeKeys.CreateInstance( - e => + (e, p) => { e.Key1 = 7711; e.Key2 = "7711"; e.Key3 = new DateTime(7711, 1, 1); }), context.EntityCompositeKeys.CreateInstance( - e => + (e, p) => { e.Key1 = 7712; e.Key2 = "7712"; e.Key3 = new DateTime(7712, 1, 1); }), context.EntityCompositeKeys.CreateInstance( - e => + (e, p) => { e.Key1 = 7713; e.Key2 = "7713"; @@ -437,15 +442,19 @@ public virtual void Can_insert_many_to_many_composite_shared_with_navs() }; var rightEntities = new[] { - context.Set().CreateInstance(e => e.Id = 7721), - context.Set().CreateInstance(e => e.Id = 7722), - context.Set().CreateInstance(e => e.Id = 7723) + context.Set().CreateInstance((e, p) => e.Id = 7721), + context.Set().CreateInstance((e, p) => e.Id = 7722), + context.Set().CreateInstance((e, p) => e.Id = 7723) }; + leftEntities[0].RootSkipShared = CreateCollection(); + leftEntities[0].RootSkipShared.Add(rightEntities[0]); // 11 - 21 leftEntities[0].RootSkipShared.Add(rightEntities[1]); // 11 - 22 leftEntities[0].RootSkipShared.Add(rightEntities[2]); // 11 - 23 + rightEntities[0].CompositeKeySkipShared = CreateCollection(); + rightEntities[0].CompositeKeySkipShared.Add(leftEntities[0]); // 21 - 11 (Dupe) rightEntities[0].CompositeKeySkipShared.Add(leftEntities[1]); // 21 - 12 rightEntities[0].CompositeKeySkipShared.Add(leftEntities[2]); // 21 - 13 @@ -499,13 +508,13 @@ public virtual void Can_update_many_to_many_composite_shared_with_navs() var leftEntities = context.Set().Include(e => e.RootSkipShared).OrderBy(e => e.Key1).ToList(); var rightEntities = context.Set().Include(e => e.CompositeKeySkipShared).ToList(); - leftEntities[0].RootSkipShared.Add(context.Set().CreateInstance(e => e.Id = 7721)); - leftEntities[0].RootSkipShared.Add(context.Set().CreateInstance(e => e.Id = 7722)); - leftEntities[0].RootSkipShared.Add(context.Set().CreateInstance(e => e.Id = 7723)); + leftEntities[0].RootSkipShared.Add(context.Set().CreateInstance((e, p) => e.Id = 7721)); + leftEntities[0].RootSkipShared.Add(context.Set().CreateInstance((e, p) => e.Id = 7722)); + leftEntities[0].RootSkipShared.Add(context.Set().CreateInstance((e, p) => e.Id = 7723)); rightEntities[0].CompositeKeySkipShared.Add( context.EntityCompositeKeys.CreateInstance( - e => + (e, p) => { e.Key1 = 7711; e.Key2 = "7711"; @@ -513,7 +522,7 @@ public virtual void Can_update_many_to_many_composite_shared_with_navs() })); rightEntities[0].CompositeKeySkipShared.Add( context.EntityCompositeKeys.CreateInstance( - e => + (e, p) => { e.Key1 = 7712; e.Key2 = "7712"; @@ -521,7 +530,7 @@ public virtual void Can_update_many_to_many_composite_shared_with_navs() })); rightEntities[0].CompositeKeySkipShared.Add( context.EntityCompositeKeys.CreateInstance( - e => + (e, p) => { e.Key1 = 7713; e.Key2 = "7713"; @@ -532,12 +541,12 @@ public virtual void Can_update_many_to_many_composite_shared_with_navs() rightEntities[1].CompositeKeySkipShared.Remove(rightEntities[1].CompositeKeySkipShared.Single(e => e.Key2 == "8_3")); leftEntities[2].RootSkipShared.Remove(leftEntities[2].RootSkipShared.Single(e => e.Id == 16)); - leftEntities[2].RootSkipShared.Add(context.Set().CreateInstance(e => e.Id = 7724)); + leftEntities[2].RootSkipShared.Add(context.Set().CreateInstance((e, p) => e.Id = 7724)); rightEntities[2].CompositeKeySkipShared.Remove(rightEntities[2].CompositeKeySkipShared.Single(e => e.Key2 == "8_2")); rightEntities[2].CompositeKeySkipShared.Add( context.EntityCompositeKeys.CreateInstance( - e => + (e, p) => { e.Key1 = 7714; e.Key2 = "7714"; @@ -727,21 +736,21 @@ public virtual void Can_insert_many_to_many_composite_additional_pk_with_navs() var leftEntities = new[] { context.EntityCompositeKeys.CreateInstance( - e => + (e, p) => { e.Key1 = 7711; e.Key2 = "7711"; e.Key3 = new DateTime(7711, 1, 1); }), context.EntityCompositeKeys.CreateInstance( - e => + (e, p) => { e.Key1 = 7712; e.Key2 = "7712"; e.Key3 = new DateTime(7712, 1, 1); }), context.EntityCompositeKeys.CreateInstance( - e => + (e, p) => { e.Key1 = 7713; e.Key2 = "7713"; @@ -750,15 +759,19 @@ public virtual void Can_insert_many_to_many_composite_additional_pk_with_navs() }; var rightEntities = new[] { - context.Set().CreateInstance(e => e.Id = 7721), - context.Set().CreateInstance(e => e.Id = 7722), - context.Set().CreateInstance(e => e.Id = 7723) + context.Set().CreateInstance((e, p) => e.Id = 7721), + context.Set().CreateInstance((e, p) => e.Id = 7722), + context.Set().CreateInstance((e, p) => e.Id = 7723) }; + leftEntities[0].ThreeSkipFull = CreateCollection(); + leftEntities[0].ThreeSkipFull.Add(rightEntities[0]); // 11 - 21 leftEntities[0].ThreeSkipFull.Add(rightEntities[1]); // 11 - 22 leftEntities[0].ThreeSkipFull.Add(rightEntities[2]); // 11 - 23 + rightEntities[0].CompositeKeySkipFull = CreateCollection(); + rightEntities[0].CompositeKeySkipFull.Add(leftEntities[0]); // 21 - 11 (Dupe) rightEntities[0].CompositeKeySkipFull.Add(leftEntities[1]); // 21 - 12 rightEntities[0].CompositeKeySkipFull.Add(leftEntities[2]); // 21 - 13 @@ -824,13 +837,13 @@ public virtual void Can_update_many_to_many_composite_additional_pk_with_navs() var leftEntities = context.Set().Include(e => e.ThreeSkipFull).OrderBy(e => e.Key1).ToList(); var rightEntities = context.Set().Include(e => e.CompositeKeySkipFull).ToList(); - leftEntities[0].ThreeSkipFull.Add(context.Set().CreateInstance(e => e.Id = 7721)); - leftEntities[0].ThreeSkipFull.Add(context.Set().CreateInstance(e => e.Id = 7722)); - leftEntities[0].ThreeSkipFull.Add(context.Set().CreateInstance(e => e.Id = 7723)); + leftEntities[0].ThreeSkipFull.Add(context.Set().CreateInstance((e, p) => e.Id = 7721)); + leftEntities[0].ThreeSkipFull.Add(context.Set().CreateInstance((e, p) => e.Id = 7722)); + leftEntities[0].ThreeSkipFull.Add(context.Set().CreateInstance((e, p) => e.Id = 7723)); rightEntities[0].CompositeKeySkipFull.Add( context.EntityCompositeKeys.CreateInstance( - e => + (e, p) => { e.Key1 = 7711; e.Key2 = "7711"; @@ -838,7 +851,7 @@ public virtual void Can_update_many_to_many_composite_additional_pk_with_navs() })); rightEntities[0].CompositeKeySkipFull.Add( context.EntityCompositeKeys.CreateInstance( - e => + (e, p) => { e.Key1 = 7712; e.Key2 = "7712"; @@ -846,7 +859,7 @@ public virtual void Can_update_many_to_many_composite_additional_pk_with_navs() })); rightEntities[0].CompositeKeySkipFull.Add( context.EntityCompositeKeys.CreateInstance( - e => + (e, p) => { e.Key1 = 7713; e.Key2 = "7713"; @@ -857,12 +870,12 @@ public virtual void Can_update_many_to_many_composite_additional_pk_with_navs() rightEntities[1].CompositeKeySkipFull.Remove(rightEntities[1].CompositeKeySkipFull.Single(e => e.Key2 == "9_2")); leftEntities[3].ThreeSkipFull.Remove(leftEntities[3].ThreeSkipFull.Single(e => e.Id == 7)); - leftEntities[3].ThreeSkipFull.Add(context.Set().CreateInstance(e => e.Id = 7724)); + leftEntities[3].ThreeSkipFull.Add(context.Set().CreateInstance((e, p) => e.Id = 7724)); rightEntities[2].CompositeKeySkipFull.Remove(rightEntities[2].CompositeKeySkipFull.Single(e => e.Key2 == "6_1")); rightEntities[2].CompositeKeySkipFull.Add( context.EntityCompositeKeys.CreateInstance( - e => + (e, p) => { e.Key1 = 7714; e.Key2 = "7714"; @@ -1116,21 +1129,25 @@ public virtual void Can_insert_many_to_many_self_shared() { var leftEntities = new[] { - context.EntityTwos.CreateInstance(e => e.Id = 7711), - context.EntityTwos.CreateInstance(e => e.Id = 7712), - context.EntityTwos.CreateInstance(e => e.Id = 7713) + context.EntityTwos.CreateInstance((e, p) => e.Id = 7711), + context.EntityTwos.CreateInstance((e, p) => e.Id = 7712), + context.EntityTwos.CreateInstance((e, p) => e.Id = 7713) }; var rightEntities = new[] { - context.EntityTwos.CreateInstance(e => e.Id = 7721), - context.EntityTwos.CreateInstance(e => e.Id = 7722), - context.EntityTwos.CreateInstance(e => e.Id = 7723) + context.EntityTwos.CreateInstance((e, p) => e.Id = 7721), + context.EntityTwos.CreateInstance((e, p) => e.Id = 7722), + context.EntityTwos.CreateInstance((e, p) => e.Id = 7723) }; + leftEntities[0].SelfSkipSharedLeft = CreateCollection(); + leftEntities[0].SelfSkipSharedLeft.Add(rightEntities[0]); // 11 - 21 leftEntities[0].SelfSkipSharedLeft.Add(rightEntities[1]); // 11 - 22 leftEntities[0].SelfSkipSharedLeft.Add(rightEntities[2]); // 11 - 23 + rightEntities[0].SelfSkipSharedRight = CreateCollection(); + rightEntities[0].SelfSkipSharedRight.Add(leftEntities[0]); // 21 - 11 (Dupe) rightEntities[0].SelfSkipSharedRight.Add(leftEntities[1]); // 21 - 12 rightEntities[0].SelfSkipSharedRight.Add(leftEntities[2]); // 21 - 13 @@ -1189,22 +1206,22 @@ public virtual void Can_update_many_to_many_self() var leftEntities = context.Set().Include(e => e.SelfSkipSharedRight).OrderBy(e => e.Id).ToList(); var rightEntities = context.Set().Include(e => e.SelfSkipSharedLeft).ToList(); - leftEntities[0].SelfSkipSharedRight.Add(context.EntityTwos.CreateInstance(e => e.Id = 7721)); - leftEntities[0].SelfSkipSharedRight.Add(context.EntityTwos.CreateInstance(e => e.Id = 7722)); - leftEntities[0].SelfSkipSharedRight.Add(context.EntityTwos.CreateInstance(e => e.Id = 7723)); + leftEntities[0].SelfSkipSharedRight.Add(context.EntityTwos.CreateInstance((e, p) => e.Id = 7721)); + leftEntities[0].SelfSkipSharedRight.Add(context.EntityTwos.CreateInstance((e, p) => e.Id = 7722)); + leftEntities[0].SelfSkipSharedRight.Add(context.EntityTwos.CreateInstance((e, p) => e.Id = 7723)); - rightEntities[0].SelfSkipSharedLeft.Add(context.EntityTwos.CreateInstance(e => e.Id = 7711)); - rightEntities[0].SelfSkipSharedLeft.Add(context.EntityTwos.CreateInstance(e => e.Id = 7712)); - rightEntities[0].SelfSkipSharedLeft.Add(context.EntityTwos.CreateInstance(e => e.Id = 7713)); + rightEntities[0].SelfSkipSharedLeft.Add(context.EntityTwos.CreateInstance((e, p) => e.Id = 7711)); + rightEntities[0].SelfSkipSharedLeft.Add(context.EntityTwos.CreateInstance((e, p) => e.Id = 7712)); + rightEntities[0].SelfSkipSharedLeft.Add(context.EntityTwos.CreateInstance((e, p) => e.Id = 7713)); leftEntities[2].SelfSkipSharedRight.Remove(leftEntities[2].SelfSkipSharedRight.Single(e => e.Id == 5)); rightEntities[1].SelfSkipSharedLeft.Remove(rightEntities[1].SelfSkipSharedLeft.Single(e => e.Id == 8)); leftEntities[4].SelfSkipSharedRight.Remove(leftEntities[4].SelfSkipSharedRight.Single(e => e.Id == 8)); - leftEntities[4].SelfSkipSharedRight.Add(context.EntityTwos.CreateInstance(e => e.Id = 7724)); + leftEntities[4].SelfSkipSharedRight.Add(context.EntityTwos.CreateInstance((e, p) => e.Id = 7724)); rightEntities[3].SelfSkipSharedLeft.Remove(rightEntities[3].SelfSkipSharedLeft.Single(e => e.Id == 9)); - rightEntities[3].SelfSkipSharedLeft.Add(context.EntityTwos.CreateInstance(e => e.Id = 7714)); + rightEntities[3].SelfSkipSharedLeft.Add(context.EntityTwos.CreateInstance((e, p) => e.Id = 7714)); if (RequiresDetectChanges) { @@ -1288,21 +1305,25 @@ public virtual void Can_insert_many_to_many_with_navs() { var leftEntities = new[] { - context.EntityTwos.CreateInstance(e => e.Id = 7711), - context.EntityTwos.CreateInstance(e => e.Id = 7712), - context.EntityTwos.CreateInstance(e => e.Id = 7713) + context.EntityTwos.CreateInstance((e, p) => e.Id = 7711), + context.EntityTwos.CreateInstance((e, p) => e.Id = 7712), + context.EntityTwos.CreateInstance((e, p) => e.Id = 7713) }; var rightEntities = new[] { - context.EntityThrees.CreateInstance(e => e.Id = 7721), - context.EntityThrees.CreateInstance(e => e.Id = 7722), - context.EntityThrees.CreateInstance(e => e.Id = 7723) + context.EntityThrees.CreateInstance((e, p) => e.Id = 7721), + context.EntityThrees.CreateInstance((e, p) => e.Id = 7722), + context.EntityThrees.CreateInstance((e, p) => e.Id = 7723) }; + leftEntities[0].ThreeSkipFull = CreateCollection(); + leftEntities[0].ThreeSkipFull.Add(rightEntities[0]); // 11 - 21 leftEntities[0].ThreeSkipFull.Add(rightEntities[1]); // 11 - 22 leftEntities[0].ThreeSkipFull.Add(rightEntities[2]); // 11 - 23 + rightEntities[0].TwoSkipFull = CreateCollection(); + rightEntities[0].TwoSkipFull.Add(leftEntities[0]); // 21 - 11 (Dupe) rightEntities[0].TwoSkipFull.Add(leftEntities[1]); // 21 - 12 rightEntities[0].TwoSkipFull.Add(leftEntities[2]); // 21 - 13 @@ -1361,22 +1382,22 @@ public virtual void Can_update_many_to_many_with_navs() var leftEntities = context.Set().Include(e => e.ThreeSkipFull).OrderBy(e => e.Id).ToList(); var rightEntities = context.Set().Include(e => e.TwoSkipFull).ToList(); - leftEntities[0].ThreeSkipFull.Add(context.EntityThrees.CreateInstance(e => e.Id = 7721)); - leftEntities[0].ThreeSkipFull.Add(context.EntityThrees.CreateInstance(e => e.Id = 7722)); - leftEntities[0].ThreeSkipFull.Add(context.EntityThrees.CreateInstance(e => e.Id = 7723)); + leftEntities[0].ThreeSkipFull.Add(context.EntityThrees.CreateInstance((e, p) => e.Id = 7721)); + leftEntities[0].ThreeSkipFull.Add(context.EntityThrees.CreateInstance((e, p) => e.Id = 7722)); + leftEntities[0].ThreeSkipFull.Add(context.EntityThrees.CreateInstance((e, p) => e.Id = 7723)); - rightEntities[0].TwoSkipFull.Add(context.EntityTwos.CreateInstance(e => e.Id = 7711)); - rightEntities[0].TwoSkipFull.Add(context.EntityTwos.CreateInstance(e => e.Id = 7712)); - rightEntities[0].TwoSkipFull.Add(context.EntityTwos.CreateInstance(e => e.Id = 7713)); + rightEntities[0].TwoSkipFull.Add(context.EntityTwos.CreateInstance((e, p) => e.Id = 7711)); + rightEntities[0].TwoSkipFull.Add(context.EntityTwos.CreateInstance((e, p) => e.Id = 7712)); + rightEntities[0].TwoSkipFull.Add(context.EntityTwos.CreateInstance((e, p) => e.Id = 7713)); leftEntities[1].ThreeSkipFull.Remove(leftEntities[1].ThreeSkipFull.Single(e => e.Id == 9)); rightEntities[1].TwoSkipFull.Remove(rightEntities[1].TwoSkipFull.Single(e => e.Id == 4)); leftEntities[2].ThreeSkipFull.Remove(leftEntities[2].ThreeSkipFull.Single(e => e.Id == 11)); - leftEntities[2].ThreeSkipFull.Add(context.EntityThrees.CreateInstance(e => e.Id = 7724)); + leftEntities[2].ThreeSkipFull.Add(context.EntityThrees.CreateInstance((e, p) => e.Id = 7724)); rightEntities[2].TwoSkipFull.Remove(rightEntities[2].TwoSkipFull.Single(e => e.Id == 6)); - rightEntities[2].TwoSkipFull.Add(context.EntityTwos.CreateInstance(e => e.Id = 7714)); + rightEntities[2].TwoSkipFull.Add(context.EntityTwos.CreateInstance((e, p) => e.Id = 7714)); if (RequiresDetectChanges) { @@ -1471,21 +1492,25 @@ public virtual void Can_insert_many_to_many_with_inheritance() { var leftEntities = new[] { - context.EntityOnes.CreateInstance(e => e.Id = 7711), - context.EntityOnes.CreateInstance(e => e.Id = 7712), - context.EntityOnes.CreateInstance(e => e.Id = 7713), + context.EntityOnes.CreateInstance((e, p) => e.Id = 7711), + context.EntityOnes.CreateInstance((e, p) => e.Id = 7712), + context.EntityOnes.CreateInstance((e, p) => e.Id = 7713), }; var rightEntities = new[] { - context.Set().CreateInstance(e => e.Id = 7721), - context.Set().CreateInstance(e => e.Id = 7722), - context.Set().CreateInstance(e => e.Id = 7723) + context.Set().CreateInstance((e, p) => e.Id = 7721), + context.Set().CreateInstance((e, p) => e.Id = 7722), + context.Set().CreateInstance((e, p) => e.Id = 7723) }; + leftEntities[0].BranchSkip = CreateCollection(); + leftEntities[0].BranchSkip.Add(rightEntities[0]); // 11 - 21 leftEntities[0].BranchSkip.Add(rightEntities[1]); // 11 - 22 leftEntities[0].BranchSkip.Add(rightEntities[2]); // 11 - 23 + rightEntities[0].OneSkip = CreateCollection(); + rightEntities[0].OneSkip.Add(leftEntities[0]); // 21 - 11 (Dupe) rightEntities[0].OneSkip.Add(leftEntities[1]); // 21 - 12 rightEntities[0].OneSkip.Add(leftEntities[2]); // 21 - 13 @@ -1536,22 +1561,22 @@ public virtual void Can_update_many_to_many_with_inheritance() var leftEntities = context.Set().Include(e => e.BranchSkip).OrderBy(e => e.Id).ToList(); var rightEntities = context.Set().Include(e => e.OneSkip).ToList(); - leftEntities[0].BranchSkip.Add(context.Set().CreateInstance(e => e.Id = 7721)); - leftEntities[0].BranchSkip.Add(context.Set().CreateInstance(e => e.Id = 7722)); - leftEntities[0].BranchSkip.Add(context.Set().CreateInstance(e => e.Id = 7723)); + leftEntities[0].BranchSkip.Add(context.Set().CreateInstance((e, p) => e.Id = 7721)); + leftEntities[0].BranchSkip.Add(context.Set().CreateInstance((e, p) => e.Id = 7722)); + leftEntities[0].BranchSkip.Add(context.Set().CreateInstance((e, p) => e.Id = 7723)); - rightEntities[0].OneSkip.Add(context.EntityOnes.CreateInstance(e => e.Id = 7711)); - rightEntities[0].OneSkip.Add(context.EntityOnes.CreateInstance(e => e.Id = 7712)); - rightEntities[0].OneSkip.Add(context.EntityOnes.CreateInstance(e => e.Id = 7713)); + rightEntities[0].OneSkip.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7711)); + rightEntities[0].OneSkip.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7712)); + rightEntities[0].OneSkip.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7713)); leftEntities[1].BranchSkip.Remove(leftEntities[1].BranchSkip.Single(e => e.Id == 16)); rightEntities[1].OneSkip.Remove(rightEntities[1].OneSkip.Single(e => e.Id == 9)); leftEntities[2].BranchSkip.Remove(leftEntities[2].BranchSkip.Single(e => e.Id == 14)); - leftEntities[2].BranchSkip.Add(context.Set().CreateInstance(e => e.Id = 7724)); + leftEntities[2].BranchSkip.Add(context.Set().CreateInstance((e, p) => e.Id = 7724)); rightEntities[2].OneSkip.Remove(rightEntities[2].OneSkip.Single(e => e.Id == 8)); - rightEntities[2].OneSkip.Add(context.EntityOnes.CreateInstance(e => e.Id = 7714)); + rightEntities[2].OneSkip.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7714)); if (RequiresDetectChanges) { @@ -1637,21 +1662,25 @@ public virtual void Can_insert_many_to_many_self_with_payload() { var leftEntities = new[] { - context.EntityOnes.CreateInstance(e => e.Id = 7711), - context.EntityOnes.CreateInstance(e => e.Id = 7712), - context.EntityOnes.CreateInstance(e => e.Id = 7713) + context.EntityOnes.CreateInstance((e, p) => e.Id = 7711), + context.EntityOnes.CreateInstance((e, p) => e.Id = 7712), + context.EntityOnes.CreateInstance((e, p) => e.Id = 7713) }; var rightEntities = new[] { - context.EntityOnes.CreateInstance(e => e.Id = 7721), - context.EntityOnes.CreateInstance(e => e.Id = 7722), - context.EntityOnes.CreateInstance(e => e.Id = 7723) + context.EntityOnes.CreateInstance((e, p) => e.Id = 7721), + context.EntityOnes.CreateInstance((e, p) => e.Id = 7722), + context.EntityOnes.CreateInstance((e, p) => e.Id = 7723) }; + leftEntities[0].SelfSkipPayloadLeft = CreateCollection(); + leftEntities[0].SelfSkipPayloadLeft.Add(rightEntities[0]); // 11 - 21 leftEntities[0].SelfSkipPayloadLeft.Add(rightEntities[1]); // 11 - 22 leftEntities[0].SelfSkipPayloadLeft.Add(rightEntities[2]); // 11 - 23 + rightEntities[0].SelfSkipPayloadRight = CreateCollection(); + rightEntities[0].SelfSkipPayloadRight.Add(leftEntities[0]); // 21 - 11 (Dupe) rightEntities[0].SelfSkipPayloadRight.Add(leftEntities[1]); // 21 - 12 rightEntities[0].SelfSkipPayloadRight.Add(leftEntities[2]); // 21 - 13 @@ -1728,22 +1757,22 @@ public virtual void Can_update_many_to_many_self_with_payload() var leftEntities = context.Set().Include(e => e.SelfSkipPayloadRight).OrderBy(e => e.Id).ToList(); var rightEntities = context.Set().Include(e => e.SelfSkipPayloadLeft).ToList(); - leftEntities[0].SelfSkipPayloadRight.Add(context.EntityOnes.CreateInstance(e => e.Id = 7721)); - leftEntities[0].SelfSkipPayloadRight.Add(context.EntityOnes.CreateInstance(e => e.Id = 7722)); - leftEntities[0].SelfSkipPayloadRight.Add(context.EntityOnes.CreateInstance(e => e.Id = 7723)); + leftEntities[0].SelfSkipPayloadRight.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7721)); + leftEntities[0].SelfSkipPayloadRight.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7722)); + leftEntities[0].SelfSkipPayloadRight.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7723)); - rightEntities[0].SelfSkipPayloadLeft.Add(context.EntityOnes.CreateInstance(e => e.Id = 7711)); - rightEntities[0].SelfSkipPayloadLeft.Add(context.EntityOnes.CreateInstance(e => e.Id = 7712)); - rightEntities[0].SelfSkipPayloadLeft.Add(context.EntityOnes.CreateInstance(e => e.Id = 7713)); + rightEntities[0].SelfSkipPayloadLeft.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7711)); + rightEntities[0].SelfSkipPayloadLeft.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7712)); + rightEntities[0].SelfSkipPayloadLeft.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7713)); leftEntities[2].SelfSkipPayloadRight.Remove(leftEntities[2].SelfSkipPayloadRight.Single(e => e.Id == 6)); rightEntities[1].SelfSkipPayloadLeft.Remove(rightEntities[1].SelfSkipPayloadLeft.Single(e => e.Id == 13)); leftEntities[4].SelfSkipPayloadRight.Remove(leftEntities[4].SelfSkipPayloadRight.Single(e => e.Id == 3)); - leftEntities[4].SelfSkipPayloadRight.Add(context.EntityOnes.CreateInstance(e => e.Id = 7724)); + leftEntities[4].SelfSkipPayloadRight.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7724)); rightEntities[4].SelfSkipPayloadLeft.Remove(rightEntities[4].SelfSkipPayloadLeft.Single(e => e.Id == 6)); - rightEntities[4].SelfSkipPayloadLeft.Add(context.EntityOnes.CreateInstance(e => e.Id = 7714)); + rightEntities[4].SelfSkipPayloadLeft.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7714)); if (RequiresDetectChanges) { @@ -1854,21 +1883,25 @@ public virtual void Can_insert_many_to_many_shared_with_payload() { var leftEntities = new[] { - context.EntityOnes.CreateInstance(e => e.Id = 7711), - context.EntityOnes.CreateInstance(e => e.Id = 7712), - context.EntityOnes.CreateInstance(e => e.Id = 7713) + context.EntityOnes.CreateInstance((e, p) => e.Id = 7711), + context.EntityOnes.CreateInstance((e, p) => e.Id = 7712), + context.EntityOnes.CreateInstance((e, p) => e.Id = 7713) }; var rightEntities = new[] { - context.EntityThrees.CreateInstance(e => e.Id = 7721), - context.EntityThrees.CreateInstance(e => e.Id = 7722), - context.EntityThrees.CreateInstance(e => e.Id = 7723) + context.EntityThrees.CreateInstance((e, p) => e.Id = 7721), + context.EntityThrees.CreateInstance((e, p) => e.Id = 7722), + context.EntityThrees.CreateInstance((e, p) => e.Id = 7723) }; + leftEntities[0].ThreeSkipPayloadFullShared = CreateCollection(); + leftEntities[0].ThreeSkipPayloadFullShared.Add(rightEntities[0]); // 11 - 21 leftEntities[0].ThreeSkipPayloadFullShared.Add(rightEntities[1]); // 11 - 22 leftEntities[0].ThreeSkipPayloadFullShared.Add(rightEntities[2]); // 11 - 23 + rightEntities[0].OneSkipPayloadFullShared = CreateCollection(); + rightEntities[0].OneSkipPayloadFullShared.Add(leftEntities[0]); // 21 - 11 (Dupe) rightEntities[0].OneSkipPayloadFullShared.Add(leftEntities[1]); // 21 - 12 rightEntities[0].OneSkipPayloadFullShared.Add(leftEntities[2]); // 21 - 13 @@ -1929,22 +1962,22 @@ public virtual void Can_update_many_to_many_shared_with_payload() var leftEntities = context.Set().Include(e => e.ThreeSkipPayloadFullShared).OrderBy(e => e.Id).ToList(); var rightEntities = context.Set().Include(e => e.OneSkipPayloadFullShared).ToList(); - leftEntities[0].ThreeSkipPayloadFullShared.Add(context.EntityThrees.CreateInstance(e => e.Id = 7721)); - leftEntities[0].ThreeSkipPayloadFullShared.Add(context.EntityThrees.CreateInstance(e => e.Id = 7722)); - leftEntities[0].ThreeSkipPayloadFullShared.Add(context.EntityThrees.CreateInstance(e => e.Id = 7723)); + leftEntities[0].ThreeSkipPayloadFullShared.Add(context.EntityThrees.CreateInstance((e, p) => e.Id = 7721)); + leftEntities[0].ThreeSkipPayloadFullShared.Add(context.EntityThrees.CreateInstance((e, p) => e.Id = 7722)); + leftEntities[0].ThreeSkipPayloadFullShared.Add(context.EntityThrees.CreateInstance((e, p) => e.Id = 7723)); - rightEntities[0].OneSkipPayloadFullShared.Add(context.EntityOnes.CreateInstance(e => e.Id = 7711)); - rightEntities[0].OneSkipPayloadFullShared.Add(context.EntityOnes.CreateInstance(e => e.Id = 7712)); - rightEntities[0].OneSkipPayloadFullShared.Add(context.EntityOnes.CreateInstance(e => e.Id = 7713)); + rightEntities[0].OneSkipPayloadFullShared.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7711)); + rightEntities[0].OneSkipPayloadFullShared.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7712)); + rightEntities[0].OneSkipPayloadFullShared.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7713)); leftEntities[2].ThreeSkipPayloadFullShared.Remove(leftEntities[2].ThreeSkipPayloadFullShared.Single(e => e.Id == 2)); rightEntities[4].OneSkipPayloadFullShared.Remove(rightEntities[4].OneSkipPayloadFullShared.Single(e => e.Id == 4)); leftEntities[3].ThreeSkipPayloadFullShared.Remove(leftEntities[3].ThreeSkipPayloadFullShared.Single(e => e.Id == 18)); - leftEntities[3].ThreeSkipPayloadFullShared.Add(context.EntityThrees.CreateInstance(e => e.Id = 7724)); + leftEntities[3].ThreeSkipPayloadFullShared.Add(context.EntityThrees.CreateInstance((e, p) => e.Id = 7724)); rightEntities[2].OneSkipPayloadFullShared.Remove(rightEntities[2].OneSkipPayloadFullShared.Single(e => e.Id == 13)); - rightEntities[2].OneSkipPayloadFullShared.Add(context.EntityOnes.CreateInstance(e => e.Id = 7714)); + rightEntities[2].OneSkipPayloadFullShared.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7714)); if (RequiresDetectChanges) { @@ -2053,21 +2086,25 @@ public virtual void Can_insert_many_to_many_shared() { var leftEntities = new[] { - context.EntityOnes.CreateInstance(e => e.Id = 7711), - context.EntityOnes.CreateInstance(e => e.Id = 7712), - context.EntityOnes.CreateInstance(e => e.Id = 7713) + context.EntityOnes.CreateInstance((e, p) => e.Id = 7711), + context.EntityOnes.CreateInstance((e, p) => e.Id = 7712), + context.EntityOnes.CreateInstance((e, p) => e.Id = 7713) }; var rightEntities = new[] { - context.EntityTwos.CreateInstance(e => e.Id = 7721), - context.EntityTwos.CreateInstance(e => e.Id = 7722), - context.EntityTwos.CreateInstance(e => e.Id = 7723) + context.EntityTwos.CreateInstance((e, p) => e.Id = 7721), + context.EntityTwos.CreateInstance((e, p) => e.Id = 7722), + context.EntityTwos.CreateInstance((e, p) => e.Id = 7723) }; + leftEntities[0].TwoSkipShared = CreateCollection(); + leftEntities[0].TwoSkipShared.Add(rightEntities[0]); // 11 - 21 leftEntities[0].TwoSkipShared.Add(rightEntities[1]); // 11 - 22 leftEntities[0].TwoSkipShared.Add(rightEntities[2]); // 11 - 23 + rightEntities[0].OneSkipShared = CreateCollection(); + rightEntities[0].OneSkipShared.Add(leftEntities[0]); // 21 - 11 (Dupe) rightEntities[0].OneSkipShared.Add(leftEntities[1]); // 21 - 12 rightEntities[0].OneSkipShared.Add(leftEntities[2]); // 21 - 13 @@ -2118,22 +2155,22 @@ public virtual void Can_update_many_to_many_shared() var leftEntities = context.Set().Include(e => e.TwoSkipShared).OrderBy(e => e.Id).ToList(); var rightEntities = context.Set().Include(e => e.OneSkipShared).ToList(); - leftEntities[0].TwoSkipShared.Add(context.EntityTwos.CreateInstance(e => e.Id = 7721)); - leftEntities[0].TwoSkipShared.Add(context.EntityTwos.CreateInstance(e => e.Id = 7722)); - leftEntities[0].TwoSkipShared.Add(context.EntityTwos.CreateInstance(e => e.Id = 7723)); + leftEntities[0].TwoSkipShared.Add(context.EntityTwos.CreateInstance((e, p) => e.Id = 7721)); + leftEntities[0].TwoSkipShared.Add(context.EntityTwos.CreateInstance((e, p) => e.Id = 7722)); + leftEntities[0].TwoSkipShared.Add(context.EntityTwos.CreateInstance((e, p) => e.Id = 7723)); - rightEntities[0].OneSkipShared.Add(context.EntityOnes.CreateInstance(e => e.Id = 7711)); - rightEntities[0].OneSkipShared.Add(context.EntityOnes.CreateInstance(e => e.Id = 7712)); - rightEntities[0].OneSkipShared.Add(context.EntityOnes.CreateInstance(e => e.Id = 7713)); + rightEntities[0].OneSkipShared.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7711)); + rightEntities[0].OneSkipShared.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7712)); + rightEntities[0].OneSkipShared.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7713)); leftEntities[1].TwoSkipShared.Remove(leftEntities[1].TwoSkipShared.Single(e => e.Id == 3)); rightEntities[1].OneSkipShared.Remove(rightEntities[1].OneSkipShared.Single(e => e.Id == 5)); leftEntities[2].TwoSkipShared.Remove(leftEntities[2].TwoSkipShared.Single(e => e.Id == 10)); - leftEntities[2].TwoSkipShared.Add(context.EntityTwos.CreateInstance(e => e.Id = 7724)); + leftEntities[2].TwoSkipShared.Add(context.EntityTwos.CreateInstance((e, p) => e.Id = 7724)); rightEntities[2].OneSkipShared.Remove(rightEntities[2].OneSkipShared.Single(e => e.Id == 7)); - rightEntities[2].OneSkipShared.Add(context.EntityOnes.CreateInstance(e => e.Id = 7714)); + rightEntities[2].OneSkipShared.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7714)); if (RequiresDetectChanges) { @@ -2219,21 +2256,25 @@ public virtual void Can_insert_many_to_many_with_payload() { var leftEntities = new[] { - context.EntityOnes.CreateInstance(e => e.Id = 7711), - context.EntityOnes.CreateInstance(e => e.Id = 7712), - context.EntityOnes.CreateInstance(e => e.Id = 7713) + context.EntityOnes.CreateInstance((e, p) => e.Id = 7711), + context.EntityOnes.CreateInstance((e, p) => e.Id = 7712), + context.EntityOnes.CreateInstance((e, p) => e.Id = 7713) }; var rightEntities = new[] { - context.EntityThrees.CreateInstance(e => e.Id = 7721), - context.EntityThrees.CreateInstance(e => e.Id = 7722), - context.EntityThrees.CreateInstance(e => e.Id = 7723) + context.EntityThrees.CreateInstance((e, p) => e.Id = 7721), + context.EntityThrees.CreateInstance((e, p) => e.Id = 7722), + context.EntityThrees.CreateInstance((e, p) => e.Id = 7723) }; + leftEntities[0].ThreeSkipPayloadFull = CreateCollection(); + leftEntities[0].ThreeSkipPayloadFull.Add(rightEntities[0]); // 11 - 21 leftEntities[0].ThreeSkipPayloadFull.Add(rightEntities[1]); // 11 - 22 leftEntities[0].ThreeSkipPayloadFull.Add(rightEntities[2]); // 11 - 23 + rightEntities[0].OneSkipPayloadFull = CreateCollection(); + rightEntities[0].OneSkipPayloadFull.Add(leftEntities[0]); // 21 - 11 (Dupe) rightEntities[0].OneSkipPayloadFull.Add(leftEntities[1]); // 21 - 12 rightEntities[0].OneSkipPayloadFull.Add(leftEntities[2]); // 21 - 13 @@ -2297,22 +2338,22 @@ public virtual void Can_update_many_to_many_with_payload() var leftEntities = context.Set().Include(e => e.ThreeSkipPayloadFull).OrderBy(e => e.Id).ToList(); var rightEntities = context.Set().Include(e => e.OneSkipPayloadFull).ToList(); - leftEntities[0].ThreeSkipPayloadFull.Add(context.EntityThrees.CreateInstance(e => e.Id = 7721)); - leftEntities[0].ThreeSkipPayloadFull.Add(context.EntityThrees.CreateInstance(e => e.Id = 7722)); - leftEntities[0].ThreeSkipPayloadFull.Add(context.EntityThrees.CreateInstance(e => e.Id = 7723)); + leftEntities[0].ThreeSkipPayloadFull.Add(context.EntityThrees.CreateInstance((e, p) => e.Id = 7721)); + leftEntities[0].ThreeSkipPayloadFull.Add(context.EntityThrees.CreateInstance((e, p) => e.Id = 7722)); + leftEntities[0].ThreeSkipPayloadFull.Add(context.EntityThrees.CreateInstance((e, p) => e.Id = 7723)); - rightEntities[0].OneSkipPayloadFull.Add(context.EntityOnes.CreateInstance(e => e.Id = 7711)); - rightEntities[0].OneSkipPayloadFull.Add(context.EntityOnes.CreateInstance(e => e.Id = 7712)); - rightEntities[0].OneSkipPayloadFull.Add(context.EntityOnes.CreateInstance(e => e.Id = 7713)); + rightEntities[0].OneSkipPayloadFull.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7711)); + rightEntities[0].OneSkipPayloadFull.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7712)); + rightEntities[0].OneSkipPayloadFull.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7713)); leftEntities[1].ThreeSkipPayloadFull.Remove(leftEntities[1].ThreeSkipPayloadFull.Single(e => e.Id == 9)); rightEntities[1].OneSkipPayloadFull.Remove(rightEntities[1].OneSkipPayloadFull.Single(e => e.Id == 4)); leftEntities[2].ThreeSkipPayloadFull.Remove(leftEntities[2].ThreeSkipPayloadFull.Single(e => e.Id == 5)); - leftEntities[2].ThreeSkipPayloadFull.Add(context.EntityThrees.CreateInstance(e => e.Id = 7724)); + leftEntities[2].ThreeSkipPayloadFull.Add(context.EntityThrees.CreateInstance((e, p) => e.Id = 7724)); rightEntities[2].OneSkipPayloadFull.Remove(rightEntities[2].OneSkipPayloadFull.Single(e => e.Id == 8)); - rightEntities[2].OneSkipPayloadFull.Add(context.EntityOnes.CreateInstance(e => e.Id = 7714)); + rightEntities[2].OneSkipPayloadFull.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7714)); if (RequiresDetectChanges) { @@ -2555,21 +2596,25 @@ public virtual void Can_insert_many_to_many() { var leftEntities = new[] { - context.EntityOnes.CreateInstance(e => e.Id = 7711), - context.EntityOnes.CreateInstance(e => e.Id = 7712), - context.EntityOnes.CreateInstance(e => e.Id = 7713) + context.EntityOnes.CreateInstance((e, p) => e.Id = 7711), + context.EntityOnes.CreateInstance((e, p) => e.Id = 7712), + context.EntityOnes.CreateInstance((e, p) => e.Id = 7713) }; var rightEntities = new[] { - context.EntityTwos.CreateInstance(e => e.Id = 7721), - context.EntityTwos.CreateInstance(e => e.Id = 7722), - context.EntityTwos.CreateInstance(e => e.Id = 7723) + context.EntityTwos.CreateInstance((e, p) => e.Id = 7721), + context.EntityTwos.CreateInstance((e, p) => e.Id = 7722), + context.EntityTwos.CreateInstance((e, p) => e.Id = 7723) }; + leftEntities[0].TwoSkip = CreateCollection(); + leftEntities[0].TwoSkip.Add(rightEntities[0]); // 11 - 21 leftEntities[0].TwoSkip.Add(rightEntities[1]); // 11 - 22 leftEntities[0].TwoSkip.Add(rightEntities[2]); // 11 - 23 + rightEntities[0].OneSkip = CreateCollection(); + rightEntities[0].OneSkip.Add(leftEntities[0]); // 21 - 11 (Dupe) rightEntities[0].OneSkip.Add(leftEntities[1]); // 21 - 12 rightEntities[0].OneSkip.Add(leftEntities[2]); // 21 - 13 @@ -2620,22 +2665,22 @@ public virtual void Can_update_many_to_many() var leftEntities = context.Set().Include(e => e.TwoSkip).OrderBy(e => e.Id).ToList(); var rightEntities = context.Set().Include(e => e.OneSkip).ToList(); - leftEntities[0].TwoSkip.Add(context.EntityTwos.CreateInstance(e => e.Id = 7721)); - leftEntities[0].TwoSkip.Add(context.EntityTwos.CreateInstance(e => e.Id = 7722)); - leftEntities[0].TwoSkip.Add(context.EntityTwos.CreateInstance(e => e.Id = 7723)); + leftEntities[0].TwoSkip.Add(context.EntityTwos.CreateInstance((e, p) => e.Id = 7721)); + leftEntities[0].TwoSkip.Add(context.EntityTwos.CreateInstance((e, p) => e.Id = 7722)); + leftEntities[0].TwoSkip.Add(context.EntityTwos.CreateInstance((e, p) => e.Id = 7723)); - rightEntities[0].OneSkip.Add(context.EntityOnes.CreateInstance(e => e.Id = 7711)); - rightEntities[0].OneSkip.Add(context.EntityOnes.CreateInstance(e => e.Id = 7712)); - rightEntities[0].OneSkip.Add(context.EntityOnes.CreateInstance(e => e.Id = 7713)); + rightEntities[0].OneSkip.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7711)); + rightEntities[0].OneSkip.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7712)); + rightEntities[0].OneSkip.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7713)); leftEntities[1].TwoSkip.Remove(leftEntities[1].TwoSkip.Single(e => e.Id == 1)); rightEntities[1].OneSkip.Remove(rightEntities[1].OneSkip.Single(e => e.Id == 1)); leftEntities[2].TwoSkip.Remove(leftEntities[2].TwoSkip.Single(e => e.Id == 1)); - leftEntities[2].TwoSkip.Add(context.EntityTwos.CreateInstance(e => e.Id = 7724)); + leftEntities[2].TwoSkip.Add(context.EntityTwos.CreateInstance((e, p) => e.Id = 7724)); rightEntities[2].OneSkip.Remove(rightEntities[2].OneSkip.Single(e => e.Id == 1)); - rightEntities[2].OneSkip.Add(context.EntityOnes.CreateInstance(e => e.Id = 7714)); + rightEntities[2].OneSkip.Add(context.EntityOnes.CreateInstance((e, p) => e.Id = 7714)); if (RequiresDetectChanges) { @@ -2806,15 +2851,15 @@ public virtual void Can_insert_many_to_many_fully_by_convention() { var leftEntities = new[] { - context.Set().CreateInstance(e => e.Id = 7711), - context.Set().CreateInstance(e => e.Id = 7712), - context.Set().CreateInstance(e => e.Id = 7713) + context.Set().CreateInstance((e, p) => e.Id = 7711), + context.Set().CreateInstance((e, p) => e.Id = 7712), + context.Set().CreateInstance((e, p) => e.Id = 7713) }; var rightEntities = new[] { - context.Set().CreateInstance(e => e.Id = 7721), - context.Set().CreateInstance(e => e.Id = 7722), - context.Set().CreateInstance(e => e.Id = 7723) + context.Set().CreateInstance((e, p) => e.Id = 7721), + context.Set().CreateInstance((e, p) => e.Id = 7722), + context.Set().CreateInstance((e, p) => e.Id = 7723) }; leftEntities[0].Bs.Add(rightEntities[0]); // 11 - 21 @@ -2883,15 +2928,15 @@ public virtual void Initial_tracking_uses_skip_navigations() { var leftEntities = new[] { - context.Set().CreateInstance(e => e.Id = 7711), - context.Set().CreateInstance(e => e.Id = 7712), - context.Set().CreateInstance(e => e.Id = 7713) + context.Set().CreateInstance((e, p) => e.Id = 7711), + context.Set().CreateInstance((e, p) => e.Id = 7712), + context.Set().CreateInstance((e, p) => e.Id = 7713) }; var rightEntities = new[] { - context.Set().CreateInstance(e => e.Id = 7721), - context.Set().CreateInstance(e => e.Id = 7722), - context.Set().CreateInstance(e => e.Id = 7723) + context.Set().CreateInstance((e, p) => e.Id = 7721), + context.Set().CreateInstance((e, p) => e.Id = 7722), + context.Set().CreateInstance((e, p) => e.Id = 7723) }; leftEntities[0].Bs.Add(rightEntities[0]); // 11 - 21 @@ -2997,11 +3042,11 @@ public virtual void Can_insert_update_delete_shared_type_entity_type() context => { var entity = context.Set>("JoinOneToThreePayloadFullShared").CreateInstance( - c => + (e, p) => { - c["OneId"] = 1; - c["ThreeId"] = 1; - c["Payload"] = "NewlyAdded"; + e["OneId"] = 1; + e["ThreeId"] = 1; + e["Payload"] = "NewlyAdded"; }); context.Set>("JoinOneToThreePayloadFullShared").Add(entity); @@ -3044,10 +3089,10 @@ public virtual void Can_insert_update_delete_proxyable_shared_type_entity_type() context => { var entity = context.Set("PST").CreateInstance( - c => + (e, p) => { - c["Id"] = 1; - c["Payload"] = "NewlyAdded"; + e["Id"] = 1; + e["Payload"] = "NewlyAdded"; }); context.Set("PST").Add(entity); @@ -3083,6 +3128,9 @@ public virtual void Can_insert_update_delete_proxyable_shared_type_entity_type() }); } + private ICollection CreateCollection() + => RequiresDetectChanges ? (ICollection)new List() : new ObservableCollection(); + protected ManyToManyTrackingTestBase(TFixture fixture) => Fixture = fixture; diff --git a/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityBranch.cs b/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityBranch.cs index 9c1820975b4..5b938601989 100644 --- a/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityBranch.cs +++ b/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityBranch.cs @@ -2,13 +2,12 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; -using System.Collections.ObjectModel; namespace Microsoft.EntityFrameworkCore.TestModels.ManyToManyModel { public class EntityBranch : EntityRoot { public virtual long Number { get; set; } - public virtual ICollection OneSkip { get; } = new ObservableCollection(); // #21684 + public virtual ICollection OneSkip { get; set; } } } diff --git a/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityCompositeKey.cs b/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityCompositeKey.cs index c0b176190b6..dcf90ec3726 100644 --- a/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityCompositeKey.cs +++ b/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityCompositeKey.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; namespace Microsoft.EntityFrameworkCore.TestModels.ManyToManyModel { @@ -15,18 +14,11 @@ public class EntityCompositeKey public virtual string Name { get; set; } - public virtual ICollection TwoSkipShared { get; } = new ObservableCollection(); // #21684 - - public virtual ICollection ThreeSkipFull { get; } = new ObservableCollection(); // #21684 - - public virtual ICollection JoinThreeFull { get; } - = new ObservableCollection(); // #21684 - - public virtual ICollection RootSkipShared { get; } = new ObservableCollection(); // #21684 - - public virtual ICollection LeafSkipFull { get; } = new ObservableCollection(); // #21684 - - public virtual ICollection JoinLeafFull { get; } - = new ObservableCollection(); // #21684 + public virtual ICollection TwoSkipShared { get; set; } + public virtual ICollection ThreeSkipFull { get; set; } + public virtual ICollection JoinThreeFull { get; set; } + public virtual ICollection RootSkipShared { get; set; } + public virtual ICollection LeafSkipFull { get; set; } + public virtual ICollection JoinLeafFull { get; set; } } } diff --git a/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityLeaf.cs b/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityLeaf.cs index 1d60dfada51..3dc6e7d60ce 100644 --- a/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityLeaf.cs +++ b/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityLeaf.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; -using System.Collections.ObjectModel; namespace Microsoft.EntityFrameworkCore.TestModels.ManyToManyModel { @@ -10,10 +9,7 @@ public class EntityLeaf : EntityBranch { public virtual bool? IsGreen { get; set; } - public virtual ICollection CompositeKeySkipFull { get; } - = new ObservableCollection(); // #21684 - - public virtual ICollection JoinCompositeKeyFull { get; } - = new ObservableCollection(); // #21684 + public virtual ICollection CompositeKeySkipFull { get; set; } + public virtual ICollection JoinCompositeKeyFull { get; set; } } } diff --git a/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityOne.cs b/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityOne.cs index b31aef1ac83..9f874748f61 100644 --- a/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityOne.cs +++ b/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityOne.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; -using System.Collections.ObjectModel; using System.ComponentModel.DataAnnotations.Schema; namespace Microsoft.EntityFrameworkCore.TestModels.ManyToManyModel @@ -13,33 +12,20 @@ public class EntityOne public virtual string Name { get; set; } public virtual EntityTwo Reference { get; set; } - public virtual ICollection Collection { get; } = new ObservableCollection(); // #21684 - - public virtual ICollection TwoSkip { get; } = new ObservableCollection(); // #21684 - - public virtual ICollection ThreeSkipPayloadFull { get; } = new ObservableCollection(); // #21684 - - public virtual ICollection JoinThreePayloadFull { get; } - = new ObservableCollection(); // #21684 + public virtual ICollection Collection { get; set; } + public virtual ICollection TwoSkip { get; set; } + public virtual ICollection ThreeSkipPayloadFull { get; set; } + public virtual ICollection JoinThreePayloadFull { get; set; } [InverseProperty("OneSkipShared")] - public virtual ICollection TwoSkipShared { get; } = new ObservableCollection(); // #21684 - - public virtual ICollection ThreeSkipPayloadFullShared { get; } = new ObservableCollection(); // #21684 - - public virtual ICollection> JoinThreePayloadFullShared { get; } - = new ObservableCollection>(); // #21684 - - public virtual ICollection SelfSkipPayloadLeft { get; } = new ObservableCollection(); // #21684 - - public virtual ICollection JoinSelfPayloadLeft { get; } - = new ObservableCollection(); // #21684 - - public virtual ICollection SelfSkipPayloadRight { get; } = new ObservableCollection(); // #21684 - - public virtual ICollection JoinSelfPayloadRight { get; } - = new ObservableCollection(); // #21684 - - public virtual ICollection BranchSkip { get; } = new ObservableCollection(); // #21684 + public virtual ICollection TwoSkipShared { get; set; } + + public virtual ICollection ThreeSkipPayloadFullShared { get; set; } + public virtual ICollection> JoinThreePayloadFullShared { get; set; } + public virtual ICollection SelfSkipPayloadLeft { get; set; } + public virtual ICollection JoinSelfPayloadLeft { get; set; } + public virtual ICollection SelfSkipPayloadRight { get; set; } + public virtual ICollection JoinSelfPayloadRight { get; set; } + public virtual ICollection BranchSkip { get; set; } } } diff --git a/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityRoot.cs b/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityRoot.cs index 50516bf007e..f433264b2ec 100644 --- a/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityRoot.cs +++ b/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityRoot.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; -using System.Collections.ObjectModel; namespace Microsoft.EntityFrameworkCore.TestModels.ManyToManyModel { @@ -10,9 +9,7 @@ public class EntityRoot { public virtual int Id { get; set; } public virtual string Name { get; set; } - public virtual ICollection ThreeSkipShared { get; } = new ObservableCollection(); // #21684 - - public virtual ICollection CompositeKeySkipShared { get; } - = new ObservableCollection(); // #21684 + public virtual ICollection ThreeSkipShared { get; set; } + public virtual ICollection CompositeKeySkipShared { get; set; } } } diff --git a/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityThree.cs b/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityThree.cs index daeae22bc01..eb3607dc956 100644 --- a/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityThree.cs +++ b/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityThree.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; -using System.Collections.ObjectModel; using System.ComponentModel.DataAnnotations.Schema; namespace Microsoft.EntityFrameworkCore.TestModels.ManyToManyModel @@ -18,26 +17,16 @@ public class EntityThree public virtual int? CollectionInverseId { get; set; } public virtual EntityTwo CollectionInverse { get; set; } - public virtual ICollection OneSkipPayloadFull { get; } = new ObservableCollection(); // #21684 - - public virtual ICollection JoinOnePayloadFull { get; } - = new ObservableCollection(); // #21684 - - public virtual ICollection TwoSkipFull { get; } = new ObservableCollection(); // #21684 - public virtual ICollection JoinTwoFull { get; } = new ObservableCollection(); // #21684 - - public virtual ICollection OneSkipPayloadFullShared { get; } = new ObservableCollection(); // #21684 - - public virtual ICollection> JoinOnePayloadFullShared { get; } - = new ObservableCollection>(); // #21684 - - public virtual ICollection CompositeKeySkipFull { get; } - = new ObservableCollection(); // #21684 - - public virtual ICollection JoinCompositeKeyFull { get; } - = new ObservableCollection(); // #21684 + public virtual ICollection OneSkipPayloadFull { get; set; } + public virtual ICollection JoinOnePayloadFull { get; set; } + public virtual ICollection TwoSkipFull { get; set; } + public virtual ICollection JoinTwoFull { get; set; } + public virtual ICollection OneSkipPayloadFullShared { get; set; } + public virtual ICollection> JoinOnePayloadFullShared { get; set; } + public virtual ICollection CompositeKeySkipFull { get; set; } + public virtual ICollection JoinCompositeKeyFull { get; set; } [InverseProperty("ThreeSkipShared")] - public virtual ICollection RootSkipShared { get; } = new ObservableCollection(); // #21684 + public virtual ICollection RootSkipShared { get; set; } } } diff --git a/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityTwo.cs b/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityTwo.cs index 9473feb2bbd..3010940a0f9 100644 --- a/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityTwo.cs +++ b/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/EntityTwo.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; -using System.Collections.ObjectModel; using System.ComponentModel.DataAnnotations.Schema; namespace Microsoft.EntityFrameworkCore.TestModels.ManyToManyModel @@ -19,17 +18,16 @@ public class EntityTwo public virtual EntityOne CollectionInverse { get; set; } public virtual EntityThree Reference { get; set; } - public virtual ICollection Collection { get; } = new ObservableCollection(); // #21684 - public virtual ICollection OneSkip { get; } = new ObservableCollection(); // #21684 - public virtual ICollection ThreeSkipFull { get; } = new ObservableCollection(); // #21684 - public virtual ICollection JoinThreeFull { get; } = new ObservableCollection(); // #21684 - public virtual ICollection SelfSkipSharedLeft { get; } = new ObservableCollection(); // #21684 - public virtual ICollection SelfSkipSharedRight { get; } = new ObservableCollection(); // #21684 + public virtual ICollection Collection { get; set; } + public virtual ICollection OneSkip { get; set; } + public virtual ICollection ThreeSkipFull { get; set; } + public virtual ICollection JoinThreeFull { get; set; } + public virtual ICollection SelfSkipSharedLeft { get; set; } + public virtual ICollection SelfSkipSharedRight { get; set; } [InverseProperty("TwoSkipShared")] - public virtual ICollection OneSkipShared { get; } = new ObservableCollection(); // #21684 + public virtual ICollection OneSkipShared { get; set; } - public virtual ICollection CompositeKeySkipShared { get; } - = new ObservableCollection(); // #21684 + public virtual ICollection CompositeKeySkipShared { get; set; } } } diff --git a/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/ManyToManyContext.cs b/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/ManyToManyContext.cs index 240e8e56c05..c3d3a9fe37b 100644 --- a/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/ManyToManyContext.cs +++ b/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/ManyToManyContext.cs @@ -29,14 +29,14 @@ public static void Seed(ManyToManyContext context) public static class ManyToManyContextExtensions { - public static TEntity CreateInstance(this DbSet set, Action configureEntity) + public static TEntity CreateInstance(this DbSet set, Action configureEntity) where TEntity : class, new() { - var entity = set.GetService().FindExtension()?.UseChangeTrackingProxies == true - ? set.CreateProxy() - : new TEntity(); + var isProxy = set.GetService().FindExtension()?.UseChangeTrackingProxies == true; - configureEntity(entity); + var entity = isProxy ? set.CreateProxy() : new TEntity(); + + configureEntity(entity, isProxy); return entity; } diff --git a/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/ManyToManyData.cs b/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/ManyToManyData.cs index 910bba75456..dea6a4de0b6 100644 --- a/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/ManyToManyData.cs +++ b/test/EFCore.Specification.Tests/TestModels/ManyToManyModel/ManyToManyData.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using Microsoft.EntityFrameworkCore.TestUtilities; @@ -318,10 +319,22 @@ private static EntityOne[] CreateOnes(ManyToManyContext context) private static EntityOne CreateEntityOne(ManyToManyContext context, int id, string name) => CreateInstance( - context?.EntityOnes, e => + context?.EntityOnes, (e, p) => { e.Id = id; e.Name = name; + e.Collection = CreateCollection(p); + e.TwoSkip = CreateCollection(p); + e.ThreeSkipPayloadFull = CreateCollection(p); + e.JoinThreePayloadFull = CreateCollection(p); + e.TwoSkipShared = CreateCollection(p); + e.ThreeSkipPayloadFullShared = CreateCollection(p); + e.JoinThreePayloadFullShared = CreateCollection>(p); + e.SelfSkipPayloadLeft = CreateCollection(p); + e.JoinSelfPayloadLeft = CreateCollection(p); + e.SelfSkipPayloadRight = CreateCollection(p); + e.JoinSelfPayloadRight = CreateCollection(p); + e.BranchSkip = CreateCollection(p); }); private static EntityTwo[] CreateTwos(ManyToManyContext context) @@ -356,12 +369,20 @@ private static EntityTwo CreateEntityTwo( int? referenceInverseId, int? collectionInverseId) => CreateInstance( - context?.EntityTwos, e => + context?.EntityTwos, (e, p) => { e.Id = id; e.Name = name; e.ReferenceInverseId = referenceInverseId; e.CollectionInverseId = collectionInverseId; + e.Collection = CreateCollection(p); + e.OneSkip = CreateCollection(p); + e.ThreeSkipFull = CreateCollection(p); + e.JoinThreeFull = CreateCollection(p); + e.SelfSkipSharedLeft = CreateCollection(p); + e.SelfSkipSharedRight = CreateCollection(p); + e.OneSkipShared = CreateCollection(p); + e.CompositeKeySkipShared = CreateCollection(p); }); private static EntityThree[] CreateThrees(ManyToManyContext context) @@ -396,12 +417,21 @@ private static EntityThree CreateEntityThree( int? referenceInverseId, int? collectionInverseId) => CreateInstance( - context?.EntityThrees, e => + context?.EntityThrees, (e, p) => { e.Id = id; e.Name = name; e.ReferenceInverseId = referenceInverseId; e.CollectionInverseId = collectionInverseId; + e.OneSkipPayloadFull = CreateCollection(p); + e.JoinOnePayloadFull = CreateCollection(p); + e.TwoSkipFull = CreateCollection(p); + e.JoinTwoFull = CreateCollection(p); + e.OneSkipPayloadFullShared = CreateCollection(p); + e.JoinOnePayloadFullShared = CreateCollection>(p); + e.CompositeKeySkipFull = CreateCollection(p); + e.JoinCompositeKeyFull = CreateCollection(p); + e.RootSkipShared = CreateCollection(p); }); private static EntityCompositeKey[] CreateCompositeKeys(ManyToManyContext context) @@ -436,12 +466,18 @@ private static EntityCompositeKey CreateEntityCompositeKey( DateTime key3, string name) => CreateInstance( - context?.EntityCompositeKeys, e => + context?.EntityCompositeKeys, (e, p) => { e.Key1 = key1; e.Key2 = key2; e.Key3 = key3; e.Name = name; + e.TwoSkipShared = CreateCollection(p); + e.ThreeSkipFull = CreateCollection(p); + e.JoinThreeFull = CreateCollection(p); + e.RootSkipShared = CreateCollection(p); + e.LeafSkipFull = CreateCollection(p); + e.JoinLeafFull = CreateCollection(p); }); private static EntityRoot[] CreateRoots(ManyToManyContext context) @@ -474,10 +510,12 @@ private static EntityRoot CreateEntityRoot( int id, string name) => CreateInstance( - context?.EntityRoots, e => + context?.EntityRoots, (e, p) => { e.Id = id; e.Name = name; + e.ThreeSkipShared = CreateCollection(p); + e.CompositeKeySkipShared = CreateCollection(p); }); private static EntityBranch CreateEntityBranch( @@ -486,11 +524,14 @@ private static EntityBranch CreateEntityBranch( string name, long number) => CreateInstance( - context?.Set(), e => + context?.Set(), (e, p) => { e.Id = id; e.Name = name; e.Number = number; + e.ThreeSkipShared = CreateCollection(p); + e.CompositeKeySkipShared = CreateCollection(p); + e.OneSkip = CreateCollection(p); }); private static EntityLeaf CreateEntityLeaf( @@ -500,12 +541,17 @@ private static EntityLeaf CreateEntityLeaf( long number, bool? isGreen) => CreateInstance( - context?.Set(), e => + context?.Set(), (e, p) => { e.Id = id; e.Name = name; e.Number = number; e.IsGreen = isGreen; + e.ThreeSkipShared = CreateCollection(p); + e.CompositeKeySkipShared = CreateCollection(p); + e.OneSkip = CreateCollection(p); + e.CompositeKeySkipFull = CreateCollection(p); + e.JoinCompositeKeyFull = CreateCollection(p); }); private static JoinCompositeKeyToLeaf[] CreateJoinCompositeKeyToLeaves(ManyToManyContext context) @@ -551,7 +597,7 @@ private static JoinCompositeKeyToLeaf CreateJoinCompositeKeyToLeaf( string compositeId2, DateTime compositeId3) => CreateInstance( - context?.Set(), e => + context?.Set(), (e, p) => { e.LeafId = leafId; e.CompositeId1 = compositeId1; @@ -599,7 +645,7 @@ private static JoinOneSelfPayload CreateJoinOneSelfPayload( int rightId, DateTime payload) => CreateInstance( - context?.Set(), e => + context?.Set(), (e, p) => { e.LeftId = leftId; e.RightId = rightId; @@ -663,7 +709,7 @@ private static JoinOneToBranch CreateJoinOneToBranch( int oneId, int branchId) => CreateInstance( - context?.Set(), e => + context?.Set(), (e, p) => { e.EntityOneId = oneId; e.EntityBranchId = branchId; @@ -795,7 +841,7 @@ private static JoinOneToThreePayloadFull CreateJoinOneToThreePayloadFull( int threeId, string payload) => CreateInstance( - context?.Set(), e => + context?.Set(), (e, p) => { e.OneId = oneId; e.ThreeId = threeId; @@ -924,7 +970,7 @@ private static JoinOneToTwo CreateJoinOneToTwo( int oneId, int twoId) => CreateInstance( - context?.Set(), e => + context?.Set(), (e, p) => { e.OneId = oneId; e.TwoId = twoId; @@ -987,7 +1033,7 @@ private static JoinThreeToCompositeKeyFull CreateJoinThreeToCompositeKeyFull( string compositeId2, DateTime compositeId3) => CreateInstance( - context?.Set(), e => + context?.Set(), (e, p) => { e.ThreeId = threeId; e.CompositeId1 = compositeId1; @@ -1057,7 +1103,7 @@ private static JoinTwoToThree CreateJoinTwoToThree( int twoId, int threeId) => CreateInstance( - context?.Set(), e => + context?.Set(), (e, p) => { e.TwoId = twoId; e.ThreeId = threeId; @@ -1118,7 +1164,7 @@ private static Dictionary CreateEntityOneEntityTwo( int oneId, int twoId) => CreateInstance( - context?.Set>("EntityOneEntityTwo"), e => + context?.Set>("EntityOneEntityTwo"), (e, p) => { e["EntityOneId"] = oneId; e["EntityTwoId"] = twoId; @@ -1175,7 +1221,7 @@ private static Dictionary CreateJoinOneToThreePayloadFullShared( int threeId, string payload) => CreateInstance( - context?.Set>("JoinOneToThreePayloadFullShared"), e => + context?.Set>("JoinOneToThreePayloadFullShared"), (e, p) => { e["OneId"] = oneId; e["ThreeId"] = threeId; @@ -1226,7 +1272,7 @@ private static Dictionary CreateJoinTwoSelfShared( int leftId, int rightId) => CreateInstance( - context?.Set>("JoinTwoSelfShared"), e => + context?.Set>("JoinTwoSelfShared"), (e, p) => { e["LeftId"] = leftId; e["RightId"] = rightId; @@ -1280,7 +1326,7 @@ private static Dictionary CreateJoinTwoToCompositeKeyShared( string compositeId2, DateTime compositeId3) => CreateInstance( - context?.Set>("JoinTwoToCompositeKeyShared"), e => + context?.Set>("JoinTwoToCompositeKeyShared"), (e, p) => { e["TwoId"] = twoId; e["CompositeId1"] = compositeId1; @@ -1327,7 +1373,7 @@ private static Dictionary CreateEntityRootEntityThree( int threeId, int rootId) => CreateInstance( - context?.Set>("EntityRootEntityThree"), e => + context?.Set>("EntityRootEntityThree"), (e, p) => { e["EntityThreeId"] = threeId; e["EntityRootId"] = rootId; @@ -1377,6 +1423,9 @@ private static Dictionary[] CreateJoinCompositeKeyToRootShareds( CreateJoinCompositeKeyToRootShared(context, 6, 9, "9_7", new DateTime(2009, 7, 1)) }; + private static ICollection CreateCollection(bool proxy) + => proxy ? (ICollection)new ObservableCollection() : new List(); + private static Dictionary CreateJoinCompositeKeyToRootShared( ManyToManyContext context, int rootId, @@ -1384,7 +1433,7 @@ private static Dictionary CreateJoinCompositeKeyToRootShared( string compositeId2, DateTime compositeId3) => CreateInstance( - context?.Set>("JoinCompositeKeyToRootShared"), e => + context?.Set>("JoinCompositeKeyToRootShared"), (e, p) => { e["RootId"] = rootId; e["CompositeId1"] = compositeId1; @@ -1392,7 +1441,7 @@ private static Dictionary CreateJoinCompositeKeyToRootShared( e["CompositeId3"] = compositeId3; }); - private static TEntity CreateInstance(DbSet set, Action configureEntity) + private static TEntity CreateInstance(DbSet set, Action configureEntity) where TEntity : class, new() { if (set != null) @@ -1401,7 +1450,7 @@ private static TEntity CreateInstance(DbSet set, Action), factory.TryFindTypeToInstantiate(typeof(object), typeof(HashSet))); - Assert.Same(typeof(List), factory.TryFindTypeToInstantiate(typeof(object), typeof(List))); + Assert.Same(typeof(CustomHashSet), factory.TryFindTypeToInstantiate(typeof(object), typeof(CustomHashSet), false)); + Assert.Same(typeof(CustomList), factory.TryFindTypeToInstantiate(typeof(object), typeof(CustomList), false)); + Assert.Same(typeof(HashSet), factory.TryFindTypeToInstantiate(typeof(object), typeof(HashSet), false)); + Assert.Same(typeof(List), factory.TryFindTypeToInstantiate(typeof(object), typeof(List), false)); Assert.Same( typeof(ObservableCollection), - factory.TryFindTypeToInstantiate(typeof(object), typeof(ObservableCollection))); + factory.TryFindTypeToInstantiate(typeof(object), typeof(ObservableCollection), false)); Assert.Same( - typeof(ObservableHashSet), factory.TryFindTypeToInstantiate(typeof(object), typeof(ObservableHashSet))); + typeof(ObservableHashSet), + factory.TryFindTypeToInstantiate(typeof(object), typeof(ObservableHashSet), false)); } [ConditionalFact] @@ -33,7 +34,15 @@ public void Returns_ObservableHashSet_if_notifying_and_assignable() { Assert.Same( typeof(ObservableHashSet), - new CollectionTypeFactory().TryFindTypeToInstantiate(typeof(DummyNotifying), typeof(ICollection))); + new CollectionTypeFactory().TryFindTypeToInstantiate(typeof(DummyNotifying), typeof(ICollection), false)); + } + + [ConditionalFact] + public void Returns_ObservableHashSet_if_full_notification_required() + { + Assert.Same( + typeof(ObservableHashSet), + new CollectionTypeFactory().TryFindTypeToInstantiate(typeof(object), typeof(ICollection), true)); } [ConditionalFact] @@ -41,15 +50,17 @@ public void Returns_HashSet_if_assignable() { var factory = new CollectionTypeFactory(); - Assert.Same(typeof(HashSet), factory.TryFindTypeToInstantiate(typeof(object), typeof(ICollection))); - Assert.Same(typeof(HashSet), factory.TryFindTypeToInstantiate(typeof(object), typeof(ISet))); - Assert.Same(typeof(HashSet), factory.TryFindTypeToInstantiate(typeof(object), typeof(IEnumerable))); + Assert.Same(typeof(HashSet), factory.TryFindTypeToInstantiate(typeof(object), typeof(ICollection), false)); + Assert.Same(typeof(HashSet), factory.TryFindTypeToInstantiate(typeof(object), typeof(ISet), false)); + Assert.Same(typeof(HashSet), factory.TryFindTypeToInstantiate(typeof(object), typeof(IEnumerable), false)); } [ConditionalFact] public void Returns_List_if_assignable() { - Assert.Same(typeof(List), new CollectionTypeFactory().TryFindTypeToInstantiate(typeof(object), typeof(IList))); + Assert.Same( + typeof(List), + new CollectionTypeFactory().TryFindTypeToInstantiate(typeof(object), typeof(IList), false)); } [ConditionalFact] @@ -57,13 +68,13 @@ public void Returns_null_when_no_usable_concrete_type_found() { var factory = new CollectionTypeFactory(); - Assert.Null(factory.TryFindTypeToInstantiate(typeof(object), typeof(PrivateConstructor))); - Assert.Null(factory.TryFindTypeToInstantiate(typeof(object), typeof(InternalConstructor))); - Assert.Null(factory.TryFindTypeToInstantiate(typeof(object), typeof(ProtectedConstructor))); - Assert.Null(factory.TryFindTypeToInstantiate(typeof(object), typeof(NoParameterlessConstructor))); - Assert.Null(factory.TryFindTypeToInstantiate(typeof(object), typeof(Abstract))); - Assert.Null(factory.TryFindTypeToInstantiate(typeof(object), typeof(object))); - Assert.Null(factory.TryFindTypeToInstantiate(typeof(object), typeof(Random))); + Assert.Null(factory.TryFindTypeToInstantiate(typeof(object), typeof(PrivateConstructor), false)); + Assert.Null(factory.TryFindTypeToInstantiate(typeof(object), typeof(InternalConstructor), false)); + Assert.Null(factory.TryFindTypeToInstantiate(typeof(object), typeof(ProtectedConstructor), false)); + Assert.Null(factory.TryFindTypeToInstantiate(typeof(object), typeof(NoParameterlessConstructor), false)); + Assert.Null(factory.TryFindTypeToInstantiate(typeof(object), typeof(Abstract), false)); + Assert.Null(factory.TryFindTypeToInstantiate(typeof(object), typeof(object), false)); + Assert.Null(factory.TryFindTypeToInstantiate(typeof(object), typeof(Random), false)); } private class CustomHashSet : HashSet