Skip to content

Commit 2a80eac

Browse files
Commit pull #174 (only half the fix is accepted)
1 parent 41ad939 commit 2a80eac

File tree

5 files changed

+150
-9
lines changed

5 files changed

+150
-9
lines changed

GraphDiff/GraphDiff.Shared/Internal/Graph/CollectionGraphNode.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,18 +83,24 @@ private object AddElement<T>(DbContext context, T existing, object updateItem, o
8383
var entityType = ObjectContext.GetObjectType(updateItem.GetType());
8484
var instance = CreateEmptyEntityWithKey(context, updateItem);
8585

86-
context.Set(entityType).Add(instance);
87-
context.Entry(instance).CurrentValues.SetValues(updateItem);
88-
89-
foreach (var childMember in Members)
86+
if (!(bool) dbCollection.GetType().GetMethod("Contains").Invoke(dbCollection, new[] {updateItem}))
9087
{
91-
childMember.Update(context, instance, updateItem);
88+
context.Set(entityType).Add(instance);
89+
context.Entry(instance).CurrentValues.SetValues(updateItem);
90+
91+
foreach (var childMember in Members)
92+
{
93+
childMember.Update(context, instance, updateItem);
94+
}
9295
}
9396

9497
updateItem = instance;
9598
}
9699

97-
dbCollection.GetType().GetMethod("Add").Invoke(dbCollection, new[] {updateItem});
100+
if (!(bool)dbCollection.GetType().GetMethod("Contains").Invoke(dbCollection, new[] { updateItem }))
101+
{
102+
dbCollection.GetType().GetMethod("Add").Invoke(dbCollection, new[] { updateItem });
103+
}
98104

99105
AttachCyclicNavigationProperty(context, existing, updateItem);
100106

GraphDiff/GraphDiff.Shared/Internal/Graph/OwnedEntityGraphNode.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,24 @@ public override void Update<T>(DbContext context, T persisted, T updating)
3636

3737
AttachCyclicNavigationProperty(context, persisted, newValue);
3838

39+
// if (dbValue != null) // make an error throw or not?
3940
foreach (var childMember in Members)
4041
childMember.Update(context, dbValue, newValue);
4142
}
4243

4344
private object CreateNewPersistedEntity<T>(DbContext context, T existing, object newValue) where T : class, new()
4445
{
46+
// TBD_79ad60a7-8091-4d0c-b5de-7373f3b8cedf: Could be accepted with an option. Otherwise, we cannot allow people by default to provide multiple entity with same ID if it's not the same.
47+
//var local = context.Set(Accessor.PropertyType).Local;
48+
//foreach (var entity in local)
49+
//{
50+
// if (entity.Equals(newValue))
51+
// {
52+
// SetValue(existing, entity);
53+
// return entity;
54+
// }
55+
//}
56+
4557
var instance = Activator.CreateInstance(newValue.GetType());
4658
SetValue(existing, instance);
4759
context.Set(Accessor.PropertyType).Add(instance);

GraphDiff/GraphDiff.Tests.Shared/Models/TestModels.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,4 +240,59 @@ public class OneToOneOneToManyAssociatedModel : Entity
240240
{
241241
public OneToOneOwnedModel OneParent { get; set; }
242242
}
243+
244+
public class ModelRoot
245+
{
246+
public Guid Id { get; set; }
247+
public virtual ICollection<ModelLevel1> MyModelsLevel1 { get; set; }
248+
}
249+
250+
public class ModelLevel1
251+
{
252+
protected bool Equals(ModelLevel1 other)
253+
{
254+
return Id.Equals(other.Id);
255+
}
256+
257+
public override bool Equals(object obj)
258+
{
259+
if (ReferenceEquals(null, obj)) return false;
260+
if (ReferenceEquals(this, obj)) return true;
261+
if (obj.GetType() != this.GetType()) return false;
262+
return Equals((ModelLevel1)obj);
263+
}
264+
265+
public override int GetHashCode()
266+
{
267+
return Id.GetHashCode();
268+
}
269+
270+
public Guid Id { get; set; }
271+
272+
public virtual ModelLevel2 ModelLevel2 { get; set; }
273+
}
274+
275+
public class ModelLevel2
276+
{
277+
protected bool Equals(ModelLevel2 other)
278+
{
279+
return Code.Equals(other.Code);
280+
}
281+
282+
public override bool Equals(object obj)
283+
{
284+
if (ReferenceEquals(null, obj)) return false;
285+
if (ReferenceEquals(this, obj)) return true;
286+
if (obj.GetType() != this.GetType()) return false;
287+
return Equals((ModelLevel2)obj);
288+
}
289+
290+
public override int GetHashCode()
291+
{
292+
return Code.GetHashCode();
293+
}
294+
295+
public Guid Code { get; set; }
296+
public string Name { get; set; }
297+
}
243298
}

GraphDiff/GraphDiff.Tests.Shared/TestDbContext.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,11 @@ protected override void OnModelCreating(DbModelBuilder modelBuilder)
6868

6969
modelBuilder.Entity<InternalKeyModel>()
7070
.HasMany(ikm => ikm.Associates)
71-
.WithRequired(ikm => ikm.Parent);
71+
.WithRequired(ikm => ikm.Parent);
72+
73+
modelBuilder.Entity<ModelRoot>().HasKey(x => x.Id).HasMany(x => x.MyModelsLevel1);
74+
modelBuilder.Entity<ModelLevel1>().HasKey(x => x.Id).HasOptional(x => x.ModelLevel2);
75+
modelBuilder.Entity<ModelLevel2>().HasKey(x => x.Code);
7276
}
7377

7478
public TestDbContext() : base("Server=localhost;Initial Catalog=GraphDiff;Integrated Security=true;Connection Timeout = 300;Persist Security Info=True;") {}

GraphDiff/GraphDiff.Tests.Shared/Tests/AddAggregateBehaviours.cs

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Data.Entity;
1+
using System;
2+
using System.Data.Entity;
23
using Microsoft.VisualStudio.TestTools.UnitTesting;
34
using RefactorThis.GraphDiff.Tests.Models;
45
using System.Linq;
@@ -9,6 +10,69 @@ namespace RefactorThis.GraphDiff.Tests.Tests
910
[TestClass]
1011
public class AddAggregateBehaviours : TestBase
1112
{
13+
[TestMethod]
14+
public void ShouldAddNewAggregateRootWithDuplicateEntityOnLevel1()
15+
{
16+
var guid = Guid.Parse("C1775DA8-61EC-47A1-ADF9-A50653820061");
17+
18+
var node1 = new ModelRoot()
19+
{
20+
Id = Guid.NewGuid(),
21+
MyModelsLevel1 = new List<ModelLevel1>()
22+
{
23+
new ModelLevel1() {Id = guid},
24+
new ModelLevel1() {Id = guid}
25+
}
26+
};
27+
28+
using (var context = new TestDbContext())
29+
{
30+
node1 = context.UpdateGraph(node1, map =>
31+
map.OwnedCollection(p => p.MyModelsLevel1,
32+
with => with.OwnedEntity(p => p.ModelLevel2)));
33+
34+
context.SaveChanges();
35+
}
36+
37+
using (var context = new TestDbContext())
38+
{
39+
var model = context.Set<ModelRoot>().Include(x => x.MyModelsLevel1).FirstOrDefault();
40+
Assert.IsTrue(model.MyModelsLevel1.All(x => x.Id == guid));
41+
}
42+
}
43+
44+
[TestMethod]
45+
public void ShouldAddNewAggregateRootWithduplicateEntityOnLevel2()
46+
{
47+
// See TBD_79ad60a7-8091-4d0c-b5de-7373f3b8cedf
48+
//var guid = Guid.Parse("C1775DA8-61EC-47A1-ADF9-A50653820061");
49+
50+
//var node1 = new ModelRoot()
51+
//{
52+
// Id = Guid.NewGuid(),
53+
// MyModelsLevel1 = new List<ModelLevel1>()
54+
// {
55+
// new ModelLevel1() {Id = Guid.NewGuid(), ModelLevel2 = new ModelLevel2() {Code = guid}},
56+
// new ModelLevel1() {Id = Guid.NewGuid(), ModelLevel2 = new ModelLevel2() {Code = guid}}
57+
// }
58+
//};
59+
60+
//using (var context = new TestDbContext())
61+
//{
62+
// node1 = context.UpdateGraph(node1, map =>
63+
// map.OwnedCollection(p => p.MyModelsLevel1,
64+
// with => with.OwnedEntity(p => p.ModelLevel2)));
65+
66+
// context.SaveChanges();
67+
//}
68+
69+
//using (var context = new TestDbContext())
70+
//{
71+
// var models = context.Set<ModelLevel1>().Include(x => x.ModelLevel2).ToList();
72+
// Assert.IsTrue(models.All(x => x.ModelLevel2.Code == guid));
73+
//}
74+
}
75+
1276
[TestMethod]
1377
public void ShouldAddNewAggregateRoot_Detached()
1478
{
@@ -44,7 +108,7 @@ public void ShouldAddNewAggregateRoot_Detached()
44108
node1 = context.UpdateGraph(node1, map => map
45109
.OwnedEntity(p => p.OneToOneOwned)
46110
.AssociatedEntity(p => p.OneToOneAssociated)
47-
.OwnedCollection(p => p.OneToManyOwned)
111+
.OwnedCollection(p => p.OneToManyOwned, with => with.OwnedEntity(p => p.OneToManyOneToOneOwned))
48112
.AssociatedCollection(p => p.OneToManyAssociated));
49113

50114
context.SaveChanges();

0 commit comments

Comments
 (0)