Skip to content

Commit 1cf3995

Browse files
committed
add support for owned entities
1 parent a377515 commit 1cf3995

12 files changed

Lines changed: 119 additions & 5 deletions

src/Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<Project>
33
<PropertyGroup>
44
<NoWarn>CS1591;NU5104;CS1573</NoWarn>
5-
<Version>15.0.2</Version>
5+
<Version>15.0.3</Version>
66
<AssemblyVersion>1.0.0</AssemblyVersion>
77
<PackageTags>EntityFrameworkCore, EntityFramework, GraphQL</PackageTags>
88
<SignAssembly>false</SignAssembly>

src/GraphQL.EntityFramework/NavigationReader.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,16 @@ static class NavigationReader
99
{
1010
public static IReadOnlyDictionary<Type, IReadOnlyList<Navigation>> GetNavigationProperties(IModel model)
1111
{
12-
return model
13-
.GetEntityTypes()
14-
.Where(x => !x.IsOwned())
15-
.ToDictionary(x => x.ClrType, GetNavigations);
12+
var dictionary = new Dictionary<Type, IReadOnlyList<Navigation>>();
13+
foreach (var property in model.GetEntityTypes())
14+
{
15+
if (!dictionary.ContainsKey(property.ClrType))
16+
{
17+
dictionary[property.ClrType] = GetNavigations(property);
18+
}
19+
}
20+
21+
return dictionary;
1622
}
1723

1824
static IReadOnlyList<Navigation> GetNavigations(IEntityType entity)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
using Microsoft.EntityFrameworkCore;
2+
3+
[Owned]
4+
public class OwnedChild
5+
{
6+
public string Property { get; set; } = null!;
7+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using GraphQL;
2+
using GraphQL.EntityFramework;
3+
4+
[GraphQLMetadata(nameof(OwnedChild))]
5+
public class OwnedChildGraph :
6+
EfObjectGraphType<IntegrationDbContext, OwnedChild>
7+
{
8+
public OwnedChildGraph(IEfGraphQLService<IntegrationDbContext> graphQlService) :
9+
base(graphQlService)
10+
{
11+
AutoMap();
12+
}
13+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System;
2+
3+
public class OwnedParent
4+
{
5+
public Guid Id { get; set; } = Guid.NewGuid();
6+
public string? Property { get; set; }
7+
8+
public OwnedChild Child1 { get; set; } = null!;
9+
public OwnedChild Child2 { get; set; } = null!;
10+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using GraphQL;
2+
using GraphQL.EntityFramework;
3+
4+
[GraphQLMetadata(nameof(OwnedParent))]
5+
public class OwnedParentGraph :
6+
EfObjectGraphType<IntegrationDbContext, OwnedParent>
7+
{
8+
public OwnedParentGraph(IEfGraphQLService<IntegrationDbContext> graphQlService) :
9+
base(graphQlService)
10+
{
11+
AutoMap();
12+
}
13+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
target:
3+
{
4+
"data": {
5+
"ownedParent": {
6+
"property": "Parent value",
7+
"child1": {
8+
"property": "Value1"
9+
}
10+
}
11+
}
12+
},
13+
sql: [
14+
{
15+
Text:
16+
SELECT TOP(2) [o].[Id], [o].[Property], [o].[Child1_Property], [o].[Child2_Property]
17+
FROM [OwnedParents] AS [o]
18+
WHERE [o].[Id] = 'Guid_1'
19+
}
20+
]
21+
}

src/Tests/IntegrationTests/IntegrationTests.SchemaPrint.verified.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,17 @@ input OrderBy {
202202
descending: Boolean
203203
}
204204

205+
type OwnedChild {
206+
property: String!
207+
}
208+
209+
type OwnedParent {
210+
child1: OwnedChild!
211+
child2: OwnedChild!
212+
id: ID!
213+
property: String
214+
}
215+
205216
type PageInfo {
206217
hasNextPage: Boolean!
207218
hasPreviousPage: Boolean!
@@ -268,6 +279,7 @@ type Query {
268279
parentEntitiesViewConnection(after: String, first: Int, before: String, last: Int, where: [WhereExpression!], orderBy: [OrderBy!]): ParentViewConnection!
269280
parentEntityView(where: [WhereExpression!]): ParentView!
270281
parentEntityViewNullable(where: [WhereExpression!]): ParentView
282+
ownedParent(id: ID, ids: [ID!], where: [WhereExpression!]): OwnedParent
271283
}
272284

273285
type SkipLevelGraph {

src/Tests/IntegrationTests/IntegrationTests.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,29 @@ public async Task Single_Found_NoTracking()
468468
await RunQuery(database, query, null, null, true, new object[] {entity1, entity2});
469469
}
470470

471+
[Fact]
472+
public async Task Owned()
473+
{
474+
var query = @"
475+
{
476+
ownedParent(id: ""00000000-0000-0000-0000-000000000001"") {
477+
property
478+
child1 {
479+
property
480+
}
481+
}
482+
}";
483+
OwnedParent entity1 = new()
484+
{
485+
Id = Guid.Parse("00000000-0000-0000-0000-000000000001"),
486+
Property = "Parent value",
487+
Child1 = new OwnedChild { Property = "Value1" },
488+
Child2 = new OwnedChild { Property = "Value2" }
489+
};
490+
await using var database = await sqlInstance.Build();
491+
await RunQuery(database, query, null, null, false, new object[] { entity1 });
492+
}
493+
471494
[Fact]
472495
public async Task Single_Found()
473496
{

src/Tests/IntegrationTests/MyDataContext.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public class IntegrationDbContext :
2525
public DbSet<ManyToManyLeftEntity> ManyToManyLeftEntities { get; set; } = null!;
2626
public DbSet<ManyToManyRightEntity> ManyToManyRightEntities { get; set; } = null!;
2727
public DbSet<ManyToManyMiddleEntity> ManyToManyMiddleEntities { get; set; } = null!;
28+
public DbSet<OwnedParent> OwnedParents { get; set; } = null!;
2829

2930
public IntegrationDbContext(DbContextOptions options) :
3031
base(options)
@@ -56,6 +57,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
5657
modelBuilder.Entity<WithManyChildrenEntity>();
5758
modelBuilder.Entity<Child1Entity>();
5859
modelBuilder.Entity<NamedIdEntity>();
60+
modelBuilder.Entity<OwnedParent>();
5961
modelBuilder.Entity<Child2Entity>();
6062
modelBuilder.Entity<DerivedEntity>().HasBaseType<InheritedEntity>();
6163
modelBuilder.Entity<DerivedWithNavigationEntity>()

0 commit comments

Comments
 (0)