Skip to content

Commit f179e80

Browse files
committed
Merge pull request #52 from SphtKr/ef-materializer-nonstandard-id-bug
EF materializer nonstandard id bug
2 parents 80bfc0b + 4ea71f2 commit f179e80

File tree

6 files changed

+132
-16
lines changed

6 files changed

+132
-16
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
using System;
2+
using System.Linq;
3+
using Microsoft.VisualStudio.TestTools.UnitTesting;
4+
using JSONAPI.EntityFramework.Tests.Models;
5+
using FluentAssertions;
6+
using System.Collections.Generic;
7+
8+
namespace JSONAPI.EntityFramework.Tests
9+
{
10+
[TestClass]
11+
public class EntityFrameworkMaterializerTests
12+
{
13+
private class NotAnEntity
14+
{
15+
public string Id { get; set; }
16+
public string Temporary { get; set; }
17+
}
18+
19+
private TestEntities context;
20+
private Backlink b1, b2;
21+
22+
[TestInitialize]
23+
public void SetupEntities()
24+
{
25+
//- See http://stackoverflow.com/a/19130718/489116
26+
var instance = System.Data.Entity.SqlServer.SqlProviderServices.Instance;
27+
//-
28+
29+
context = new TestEntities();
30+
//JSONAPI.EntityFramework.Json.ContractResolver.ObjectContext = context;
31+
32+
33+
// Clear it out!
34+
foreach (Backlink o in context.Backlinks) context.Backlinks.Remove(o);
35+
context.SaveChanges();
36+
37+
b1 = new Backlink
38+
{
39+
Url = "http://www.google.com/",
40+
Snippet = "1 Results"
41+
};
42+
43+
context.SaveChanges();
44+
}
45+
46+
[TestMethod]
47+
public void GetKeyNamesStandardIdTest()
48+
{
49+
// Arrange
50+
var materializer = new EntityFrameworkMaterializer(context);
51+
52+
// Act
53+
IEnumerable<string> keyNames = materializer.GetKeyNames(typeof(Post));
54+
55+
// Assert
56+
keyNames.Count().Should().Be(1);
57+
keyNames.First().Should().Be("Id");
58+
}
59+
60+
[TestMethod]
61+
public void GetKeyNamesNonStandardIdTest()
62+
{
63+
// Arrange
64+
var materializer = new EntityFrameworkMaterializer(context);
65+
66+
// Act
67+
IEnumerable<string> keyNames = materializer.GetKeyNames(typeof(Backlink));
68+
69+
// Assert
70+
keyNames.Count().Should().Be(1);
71+
keyNames.First().Should().Be("Url");
72+
}
73+
74+
[TestMethod]
75+
[ExpectedException(typeof(System.ArgumentException))]
76+
public void GetKeyNamesNotAnEntityTest()
77+
{
78+
// Arrange
79+
var materializer = new EntityFrameworkMaterializer(context);
80+
81+
// Act
82+
IEnumerable<string> keyNames = materializer.GetKeyNames(typeof(NotAnEntity));
83+
84+
// Assert
85+
Assert.Fail("A System.ArgumentException should be thrown, this assertion should be unreachable!");
86+
}
87+
}
88+
}

JSONAPI.EntityFramework.Tests/JSONAPI.EntityFramework.Tests.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,13 @@
9191
<ItemGroup>
9292
<Compile Include="ActionFilters\EnumerateQueryableAsyncAttributeTests.cs" />
9393
<Compile Include="EntityConverterTests.cs" />
94+
<Compile Include="EntityFrameworkMaterializerTests.cs" />
9495
<Compile Include="Helpers\TestDbAsyncEnumerable.cs" />
9596
<Compile Include="Helpers\WaitsUntilCancellationDbAsyncEnumerator.cs" />
9697
<Compile Include="Helpers\TestDbAsyncEnumerator.cs" />
9798
<Compile Include="Helpers\TestDbAsyncQueryProvider.cs" />
9899
<Compile Include="Models\Author.cs" />
100+
<Compile Include="Models\Backlink.cs" />
99101
<Compile Include="Models\Comment.cs" />
100102
<Compile Include="Models\TestEntities.cs" />
101103
<Compile Include="Models\Post.cs" />
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using JSONAPI.Attributes;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
7+
namespace JSONAPI.EntityFramework.Tests.Models
8+
{
9+
public class Backlink
10+
{
11+
[UseAsId]
12+
[System.ComponentModel.DataAnnotations.Key]
13+
public string Url { get; set; }
14+
15+
public Post Post { get; set; }
16+
public string Snippet { get; set; }
17+
}
18+
}

JSONAPI.EntityFramework.Tests/Models/TestEntities.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,21 @@
66

77
public partial class TestEntities : DbContext
88
{
9+
private class TestEntitiesInitializer : DropCreateDatabaseIfModelChanges<TestEntities> { }
10+
911
public TestEntities()
1012
: base("name=TestEntities")
1113
{
1214
}
1315

1416
protected override void OnModelCreating(DbModelBuilder modelBuilder)
1517
{
16-
//throw new UnintentionalCodeFirstException();
18+
Database.SetInitializer<TestEntities>(new TestEntitiesInitializer());
1719
}
1820

1921
public virtual DbSet<Author> Authors { get; set; }
2022
public virtual DbSet<Post> Posts { get; set; }
2123
public virtual DbSet<Comment> Comments { get; set; }
24+
public virtual DbSet<Backlink> Backlinks { get; set; }
2225
}
2326
}

JSONAPI.EntityFramework/EntityFrameworkMaterializer.cs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -184,25 +184,28 @@ private Type GetSingleType(Type type)
184184
return type;
185185
}
186186

187-
protected virtual IEnumerable<string> GetKeyNames(Type type)
187+
protected internal virtual IEnumerable<string> GetKeyNames(Type type)
188188
{
189-
try
190-
{
191-
// If this fails, type must not be in the context!!!
192-
ObjectContext objectContext = ((IObjectContextAdapter)this.context).ObjectContext;
193-
IEnumerable<string> retval = (IEnumerable<string>)objectContext.MetadataWorkspace
194-
.GetType(type.Name, type.Namespace, System.Data.Entity.Core.Metadata.Edm.DataSpace.CSpace)
195-
.MetadataProperties
196-
.Where(mp => mp.Name == "KeyMembers")
197-
.First()
198-
.Value;
199-
return retval;
189+
ObjectContext objectContext = ((IObjectContextAdapter)this.context).ObjectContext;
190+
System.Data.Entity.Core.Metadata.Edm.EdmType meta;
191+
try {
192+
meta = objectContext.MetadataWorkspace
193+
.GetType(type.Name, type.Namespace, System.Data.Entity.Core.Metadata.Edm.DataSpace.CSpace);
200194
}
201-
catch (Exception e)
195+
catch (System.ArgumentException e)
202196
{
203-
// Type is not an entity type in the context. Um...now what? Either override this in a subclass, or we'll assume it's "Id"!
204-
return new string[] { "Id" };
197+
throw new ArgumentException(
198+
String.Format("The Type {0} was not found in the DbContext with Type {1}", type.Name, this.context.GetType().Name),
199+
e
200+
);
205201
}
202+
var members = (IEnumerable<System.Data.Entity.Core.Metadata.Edm.EdmMember>)meta
203+
.MetadataProperties
204+
.Where(mp => mp.Name == "KeyMembers")
205+
.First()
206+
.Value;
207+
IEnumerable<string> retval = members.Select(m => m.Name);
208+
return retval;
206209
}
207210

208211
/// <summary>

JSONAPI.EntityFramework/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
// The following GUID is for the ID of the typelib if this project is exposed to COM
2323
[assembly: Guid("cdabab0c-3332-4b93-8cb6-ad521265a701")]
2424

25+
[assembly: InternalsVisibleTo("JSONAPI.EntityFramework.Tests")]
26+
2527
// Version information for an assembly consists of the following four values:
2628
//
2729
// Major Version

0 commit comments

Comments
 (0)