Skip to content

Commit 1fd0451

Browse files
Merge pull request #183 from Lempireqc/master
save
2 parents e5fcb93 + 0b68dbe commit 1fd0451

File tree

11 files changed

+389
-16
lines changed

11 files changed

+389
-16
lines changed

GraphDiff/GraphDiff.Shared/Internal/Extensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ internal static string GetEntitySetName(this IObjectContextAdapter context, Type
5959
/// <returns>The entity type by type.</returns>
6060
/// not support class in generic class
6161
internal static EntityType GetEntityTypeByType(this MetadataWorkspace metadataWorkspace, Type entityType)
62-
{
63-
string name = entityType.FullName.Replace("+", ".");
62+
{
63+
string name = ObjectContext.GetObjectType(entityType).FullName.Replace("+", ".");
6464
var lenght = name.IndexOf("`");
6565

6666
if (lenght != -1)

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

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -149,17 +149,26 @@ protected override IEnumerable<string> GetRequiredNavigationPropertyIncludes(DbC
149149

150150
private Type GetCollectionElementType()
151151
{
152-
if (Accessor.PropertyType.IsArray)
153-
{
154-
return Accessor.PropertyType.GetElementType();
155-
}
156-
157-
if (Accessor.PropertyType.IsGenericType)
158-
{
159-
return Accessor.PropertyType.GetGenericArguments()[0];
160-
}
152+
return GetCollectionElementType(Accessor.PropertyType);
153+
}
161154

162-
throw new InvalidOperationException("GraphDiff requires the collection to be either IEnumerable<T> or T[]");
155+
// Z.EntityFramework.Plus\shared\Z.EF.Plus.QueryIncludeOptimized.Shared\QueryIncludeOptimizedNullCollection.cs + Keep Array logique.
156+
private static Type GetCollectionElementType(Type propertyType)
157+
{
158+
if (propertyType.IsArray)
159+
{
160+
return propertyType.GetElementType();
161+
}
162+
else if (propertyType.GetGenericArguments().Length == 1 && typeof(IEnumerable).IsAssignableFrom(propertyType))
163+
{
164+
return propertyType.GetGenericArguments()[0];
165+
}
166+
else if (propertyType.BaseType != null && propertyType.BaseType != typeof(object))
167+
{
168+
return GetCollectionElementType(propertyType.BaseType);
169+
}
170+
171+
throw new InvalidOperationException("GraphDiff requires the collection to be either IEnumerable<T> or T[]");
163172
}
164173
}
165174
}

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,25 @@ public class NullableKeyModel
112112
public Guid? Id { get; set; }
113113
}
114114

115+
// Generic Collection models:
116+
public class SimpleTitleModel
117+
{
118+
[Key]
119+
public string Title { get; set; }
120+
}
121+
122+
public class CollectionFromListModel : List<SimpleTitleModel>
123+
{
124+
125+
}
126+
127+
public class CollectionFromListEntity : Entity
128+
{
129+
public CollectionFromListModel CollectionItems { get; set; }
130+
131+
public List<SimpleTitleModel> SimpleTitleItems { get; set; }
132+
}
133+
115134
// ====================================
116135
// Second tier models
117136
// ====================================

GraphDiff/GraphDiff.Tests.Shared/TestDbContext.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ namespace RefactorThis.GraphDiff.Tests
66
{
77
public class TestDbContext : DbContext
88
{
9+
public IDbSet<CollectionFromListEntity> CollectionFromListEntities { get; set; }
910
public IDbSet<TestNode> Nodes { get; set; }
1011
public IDbSet<TestNodeWithBaseReference> NodesWithReference { get; set; }
1112

@@ -61,9 +62,9 @@ protected override void OnModelCreating(DbModelBuilder modelBuilder)
6162

6263
modelBuilder.Entity<InternalKeyModel>()
6364
.HasMany(ikm => ikm.Associates)
64-
.WithRequired(ikm => ikm.Parent);
65-
}
65+
.WithRequired(ikm => ikm.Parent);
66+
}
6667

67-
public TestDbContext() : base("Server=localhost;Initial Catalog=GraphDiff;Integrated Security=true;Connection Timeout = 300;Persist Security Info=True;") {}
68+
public TestDbContext() : base("Server=localhost;Initial Catalog=GraphDiff;Integrated Security=true;Connection Timeout = 300;Persist Security Info=True;") {}
6869
}
6970
}

GraphDiff/GraphDiff.Tests.Shared/Tests/OwnedCollectionBehaviours.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,5 +341,44 @@ public void ShouldMergeTwoCollectionsAndDecideOnUpdatesDeletesAndAdds()
341341
Assert.IsTrue(list[3].Title == "Finish");
342342
}
343343
}
344+
345+
[TestMethod]
346+
public void ShouldWorkWithListEntities()
347+
{
348+
var source = new CollectionFromListEntity()
349+
{
350+
CollectionItems = new CollectionFromListModel()
351+
{
352+
new SimpleTitleModel() { Title = "Test" }
353+
},
354+
SimpleTitleItems = new List<SimpleTitleModel>()
355+
{
356+
new SimpleTitleModel() { Title = "Old" }
357+
}
358+
};
359+
using (var context = new TestDbContext())
360+
{
361+
context.CollectionFromListEntities.Add(source);
362+
context.SaveChanges();
363+
}
364+
365+
var newExpectedCollectionValue = "New Collection Value";
366+
var newExpectedSimpleValue = "New Simple Value";
367+
source.CollectionItems[0].Title = newExpectedCollectionValue;
368+
source.SimpleTitleItems[0].Title = newExpectedSimpleValue;
369+
370+
using (var context = new TestDbContext())
371+
{
372+
context.UpdateGraph(source, map => map.OwnedCollection(c => c.CollectionItems).OwnedCollection(c => c.SimpleTitleItems));
373+
context.SaveChanges();
374+
375+
var reloaded = context.CollectionFromListEntities
376+
.Include(x => x.CollectionItems)
377+
.Include(x => x.SimpleTitleItems).FirstOrDefault(c => c.Id == source.Id);
378+
379+
Assert.AreEqual(newExpectedCollectionValue, reloaded.CollectionItems[0].Title);
380+
Assert.AreEqual(newExpectedSimpleValue, reloaded.SimpleTitleItems[0].Title);
381+
}
382+
}
344383
}
345384
}

GraphDiff/GraphDiff.sln

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GraphDiff.NetStandard21", "
1919
EndProject
2020
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "GraphDiff.Tests.Shared", "GraphDiff.Tests.Shared\GraphDiff.Tests.Shared.shproj", "{F49226DD-5BF7-482D-B2A3-88CBE41D018B}"
2121
EndProject
22-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GraphDiff.Tests.NetStandard21", "GraphDiff.Tests.NetStandard21\GraphDiff.Tests.NetStandard21.csproj", "{082C0151-CBE3-476B-B40C-0D909E83D198}"
22+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GraphDiff.Tests.NetStandard21", "GraphDiff.Tests.NetStandard21\GraphDiff.Tests.NetStandard21.csproj", "{082C0151-CBE3-476B-B40C-0D909E83D198}"
23+
EndProject
24+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Z.EntityFrameworkGraphDiff.labEF6", "Z.EntityFrameworkGraphDiff.labEF6\Z.EntityFrameworkGraphDiff.labEF6.csproj", "{1AD6B94A-4A02-4DD9-8AEB-76AE73A6E20A}"
2325
EndProject
2426
Global
2527
GlobalSection(SharedMSBuildProjectFiles) = preSolution
@@ -49,6 +51,10 @@ Global
4951
{082C0151-CBE3-476B-B40C-0D909E83D198}.Debug|Any CPU.Build.0 = Debug|Any CPU
5052
{082C0151-CBE3-476B-B40C-0D909E83D198}.Release|Any CPU.ActiveCfg = Release|Any CPU
5153
{082C0151-CBE3-476B-B40C-0D909E83D198}.Release|Any CPU.Build.0 = Release|Any CPU
54+
{1AD6B94A-4A02-4DD9-8AEB-76AE73A6E20A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
55+
{1AD6B94A-4A02-4DD9-8AEB-76AE73A6E20A}.Debug|Any CPU.Build.0 = Debug|Any CPU
56+
{1AD6B94A-4A02-4DD9-8AEB-76AE73A6E20A}.Release|Any CPU.ActiveCfg = Release|Any CPU
57+
{1AD6B94A-4A02-4DD9-8AEB-76AE73A6E20A}.Release|Any CPU.Build.0 = Release|Any CPU
5258
EndGlobalSection
5359
GlobalSection(SolutionProperties) = preSolution
5460
HideSolutionNode = FALSE
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Data.Entity;
4+
using System.Data.SqlClient;
5+
using System.Text;
6+
7+
namespace Z.EntityFrameworkGraphDiff.labEF6
8+
{
9+
class My
10+
{
11+
public static string DataBaseName = "LabGraph";
12+
// [REPLACE] is in Beta.
13+
public static string ConnectionString =
14+
("Server=[REPLACE];Initial Catalog = [BD]; Integrated Security = true; Connection Timeout = 35; Persist Security Info=True").Replace("[REPLACE]", Environment.MachineName).Replace("[BD]", DataBaseName);
15+
public static string FirstConnectionString =
16+
("Server=localhost;Initial Catalog = master; Integrated Security = true; Connection Timeout = 35; Persist Security Info=True");
17+
18+
public static void DeleteBD(DbContext context)
19+
{
20+
context.Database.Delete();
21+
}
22+
23+
public static void CreateBD(DbContext context)
24+
{
25+
try
26+
{
27+
context.Database.CreateIfNotExists();
28+
if (!context.Database.CompatibleWithModel(throwIfNoMetadata: true))
29+
{
30+
throw new Exception("Delete and Create DataBase");
31+
}
32+
}
33+
catch
34+
{
35+
try
36+
{
37+
My.DeleteBD(context);
38+
}
39+
catch (Exception e)
40+
{
41+
using (var commande = new SqlCommand("ALTER DATABASE " + DataBaseName + " SET SINGLE_USER WITH ROLLBACK IMMEDIATE;DROP DATABASE " + DataBaseName + " ;", new SqlConnection(My.ConnectionString)))
42+
{
43+
commande.Connection.Open();
44+
commande.ExecuteNonQuery();
45+
}
46+
}
47+
context.Database.CreateIfNotExists();
48+
}
49+
}
50+
}
51+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System;
2+
3+
namespace Z.EntityFrameworkGraphDiff.labEF6
4+
{
5+
class Program
6+
{
7+
static void Main(string[] args)
8+
{
9+
Request_LazyLoad.Execute();
10+
}
11+
}
12+
}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Data.Entity;
4+
using System.Linq;
5+
using System.Text;
6+
using RefactorThis.GraphDiff;
7+
8+
namespace Z.EntityFrameworkGraphDiff.labEF6
9+
{
10+
public class Request_LazyLoad
11+
{
12+
public static void Execute()
13+
{
14+
// Create BD
15+
using (var context = new EntityContext())
16+
{
17+
My.CreateBD(context);
18+
}
19+
20+
// CLEAN
21+
using (var context = new EntityContext())
22+
{
23+
context.EntitySimples.RemoveRange(context.EntitySimples);
24+
context.EntitySimpleChilds.RemoveRange(context.EntitySimpleChilds);
25+
context.EntitySimpleLists.RemoveRange(context.EntitySimpleLists);
26+
27+
context.SaveChanges();
28+
}
29+
30+
var entity = new EntitySimple { ColumnInt = 0 };
31+
// SEED
32+
using (var context = new EntityContext())
33+
{
34+
entity.EntitySimpleChild = new EntitySimpleChild() { ColumnInt = 1 };
35+
var EntitySimpleLists = new List<EntitySimpleList>() { new EntitySimpleList() { ColumnInt = 2 }, new EntitySimpleList() { ColumnInt = 3 } };
36+
37+
context.EntitySimples.Add(entity);
38+
39+
context.EntitySimpleLists.AddRange(EntitySimpleLists);
40+
context.SaveChanges();
41+
}
42+
43+
EntitySimpleList entityChildList = null;
44+
using (var context = new EntityContext())
45+
{
46+
entity = context.EntitySimples.Include(x => x.EntitySimpleChild).First();
47+
entityChildList = context.EntitySimpleLists.First();
48+
entity.EntitySimpleLists = new List<EntitySimpleList>() { entityChildList };
49+
}
50+
51+
entityChildList.ColumnInt = 20;
52+
entityChildList.EntitySimpleList2s = new List<EntitySimpleList2>() {new EntitySimpleList2()};
53+
54+
// TEST
55+
using (var context = new EntityContext())
56+
{
57+
58+
context.UpdateGraph(entity, map => map.AssociatedEntity(c => entity.EntitySimpleLists).AssociatedCollection(c => c.EntitySimpleLists));
59+
//context.UpdateGraph(entity.EntitySimpleLists.First(), map => map.AssociatedEntity(c => c.EntitySimpleList2s));
60+
context.SaveChanges();
61+
}
62+
63+
using (var context = new EntityContext())
64+
{
65+
var a = context.EntitySimples.ToList();
66+
var b = context.EntitySimpleChilds.ToList();
67+
var c = context.EntitySimpleLists.ToList();
68+
}
69+
}
70+
71+
public class EntityContext : DbContext
72+
{
73+
public EntityContext() : base(My.ConnectionString)
74+
{
75+
}
76+
77+
public DbSet<EntitySimple> EntitySimples { get; set; }
78+
public DbSet<EntitySimpleChild> EntitySimpleChilds { get; set; }
79+
public DbSet<EntitySimpleList> EntitySimpleLists { get; set; }
80+
public DbSet<EntitySimpleList2> EntitySimpleList2s { get; set; }
81+
82+
protected override void OnModelCreating(DbModelBuilder modelBuilder)
83+
{
84+
base.OnModelCreating(modelBuilder);
85+
Configuration.LazyLoadingEnabled = true;
86+
Configuration.ProxyCreationEnabled = true;
87+
}
88+
}
89+
90+
public class EntitySimple
91+
{
92+
public int ID { get; set; }
93+
public int ColumnInt { get; set; }
94+
public String ColumnString { get; set; }
95+
96+
public virtual EntitySimpleChild EntitySimpleChild { get; set; }
97+
public virtual ICollection<EntitySimpleList> EntitySimpleLists { get; set; }
98+
}
99+
100+
101+
public class EntitySimpleChild
102+
{
103+
public int ID { get; set; }
104+
public int ColumnInt { get; set; }
105+
public String ColumnString { get; set; }
106+
public virtual ICollection<EntitySimpleList2> EntitySimpleList2s { get; set; }
107+
}
108+
public class EntitySimpleList
109+
{
110+
public int ID { get; set; }
111+
public int ColumnInt { get; set; }
112+
public String ColumnString { get; set; }
113+
public virtual ICollection<EntitySimpleList2> EntitySimpleList2s { get; set; }
114+
}
115+
116+
public class EntitySimpleList2
117+
{
118+
public int ID { get; set; }
119+
public int ColumnInt { get; set; }
120+
public String ColumnString { get; set; }
121+
}
122+
}
123+
}

0 commit comments

Comments
 (0)