Skip to content

Commit 7a2fe13

Browse files
authored
Fix for id filter being ignored (#771)
1 parent 5999694 commit 7a2fe13

9 files changed

Lines changed: 229 additions & 40 deletions

docs/configuration.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -433,9 +433,9 @@ The `GraphQlController` can be tested using the [ASP.NET Integration tests](http
433433
[UsesVerify]
434434
public class GraphQlControllerTests
435435
{
436-
static HttpClient client = null!;
436+
static HttpClient client;
437437
static ClientQueryExecutor clientQueryExecutor;
438-
static WebSocketClient webSocket = null!;
438+
static WebSocketClient webSocket;
439439

440440
static GraphQlControllerTests()
441441
{

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>19.2.0</Version>
5+
<Version>19.2.1</Version>
66
<AssemblyVersion>1.0.0</AssemblyVersion>
77
<PackageTags>EntityFrameworkCore, EntityFramework, GraphQL</PackageTags>
88
<ImplicitUsings>true</ImplicitUsings>

src/GraphQL.EntityFramework/Where/ArgumentProcessor_Queryable.cs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,6 @@ public static IQueryable<TItem> ApplyGraphQlArguments<TItem>(
1919
var predicate = ExpressionBuilder<TItem>.BuildPredicate(keyName, Comparison.In, values);
2020
queryable = queryable.Where(predicate);
2121
}
22-
23-
if (ArgumentReader.TryReadId(GetArguments, out var value))
24-
{
25-
var keyName = GetKeyName(keyNames);
26-
var predicate = ExpressionBuilder<TItem>.BuildPredicate(keyName, Comparison.Equal, new[] {value});
27-
queryable = queryable.Where(predicate);
28-
}
2922
}
3023

3124
if (ArgumentReader.TryReadWhere(GetArguments, out var wheres))

src/GraphQL.EntityFramework/Where/ArgumentReader.cs

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,48 +9,45 @@ public static bool TryReadWhere(Func<Type, string, object?> getArgument, out IEn
99

1010
public static IEnumerable<OrderBy> ReadOrderBy(Func<Type, string, object?> getArgument) => getArgument.ReadList<OrderBy>("orderBy");
1111

12-
public static bool TryReadIds(Func<Type, string, object?> getArgument, [NotNullWhen(returnValue: true)] out string[]? expression)
12+
public static bool TryReadIds(Func<Type, string, object?> getArgument, [NotNullWhen(returnValue: true)] out string[]? result)
1313
{
14-
var argument = getArgument(typeof(object), "ids");
15-
if (argument is null)
14+
string ArgumentToExpression(object argument)
1615
{
17-
expression = null;
18-
return false;
16+
return argument switch
17+
{
18+
long l => l.ToString(CultureInfo.InvariantCulture),
19+
int i => i.ToString(CultureInfo.InvariantCulture),
20+
string s => s,
21+
_ => throw new($"TryReadId got an 'id' argument of type '{argument.GetType().FullName}' which is not supported.")
22+
};
1923
}
2024

21-
if (argument is IEnumerable<object> objCollection)
25+
var idsArgument = getArgument(typeof(object), "ids");
26+
var idArgument = getArgument(typeof(object), "id");
27+
if (idsArgument is null && idArgument is null)
2228
{
23-
expression = objCollection.Select(o => o.ToString()).ToArray()!;
24-
return true;
29+
result = null;
30+
return false;
2531
}
2632

27-
throw new($"TryReadIds got an 'ids' argument of type '{argument.GetType().FullName}' which is not supported.");
28-
}
33+
var expressions = new List<string>();
2934

30-
public static bool TryReadId(Func<Type, string, object?> getArgument, [NotNullWhen(returnValue: true)] out string? expression)
31-
{
32-
var argument = getArgument(typeof(object), "id");
33-
if (argument is null)
35+
if (idArgument is not null)
3436
{
35-
expression = null;
36-
return false;
37+
expressions.Add( ArgumentToExpression(idArgument));
3738
}
3839

39-
switch (argument)
40+
if (idsArgument is not null)
4041
{
41-
case long l:
42-
expression = l.ToString(CultureInfo.InvariantCulture);
43-
break;
44-
case int i:
45-
expression = i.ToString(CultureInfo.InvariantCulture);
46-
break;
47-
case string s:
48-
expression = s;
49-
break;
50-
default:
51-
throw new($"TryReadId got an 'id' argument of type '{argument.GetType().FullName}' which is not supported.");
42+
if (idsArgument is not IEnumerable<object> objCollection)
43+
{
44+
throw new($"TryReadIds got an 'ids' argument of type '{idsArgument.GetType().FullName}' which is not supported.");
45+
}
46+
47+
expressions.AddRange(objCollection.Select(ArgumentToExpression));
5248
}
5349

50+
result = expressions.ToArray();
5451
return true;
5552
}
5653

src/SampleWeb.Tests/GraphQlControllerTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
[UsesVerify]
1010
public class GraphQlControllerTests
1111
{
12-
static HttpClient client = null!;
12+
static HttpClient client;
1313
static ClientQueryExecutor clientQueryExecutor;
14-
static WebSocketClient webSocket = null!;
14+
static WebSocketClient webSocket;
1515

1616
static GraphQlControllerTests()
1717
{
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
target:
3+
{
4+
"data": {
5+
"parentEntities": [
6+
{
7+
"property": "Value1",
8+
"children": [
9+
{
10+
"property": "Child1"
11+
}
12+
]
13+
}
14+
]
15+
}
16+
},
17+
sql: [
18+
{
19+
HasTransaction: false,
20+
Text:
21+
SELECT [p].[Id], [p].[Property], [c].[Id], [c].[Nullable], [c].[ParentId], [c].[Property]
22+
FROM [ParentEntities] AS [p]
23+
LEFT JOIN [ChildEntities] AS [c] ON [p].[Id] = [c].[ParentId]
24+
ORDER BY [p].[Id]
25+
}
26+
]
27+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
target:
3+
{
4+
"data": {
5+
"parentEntities": [
6+
{
7+
"property": "Value1",
8+
"children": [
9+
{
10+
"property": "Child2"
11+
},
12+
{
13+
"property": "Child1"
14+
}
15+
]
16+
}
17+
]
18+
}
19+
},
20+
sql: [
21+
{
22+
HasTransaction: false,
23+
Text:
24+
SELECT [p].[Id], [p].[Property], [c].[Id], [c].[Nullable], [c].[ParentId], [c].[Property]
25+
FROM [ParentEntities] AS [p]
26+
LEFT JOIN [ChildEntities] AS [c] ON [p].[Id] = [c].[ParentId]
27+
WHERE [p].[Id] = 'Guid_1'
28+
ORDER BY [p].[Id]
29+
}
30+
]
31+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
target:
3+
{
4+
"data": {
5+
"parentEntities": [
6+
{
7+
"property": "Value1",
8+
"children": [
9+
{
10+
"property": "Child1"
11+
}
12+
]
13+
}
14+
]
15+
}
16+
},
17+
sql: [
18+
{
19+
HasTransaction: false,
20+
Text:
21+
SELECT [p].[Id], [p].[Property], [c].[Id], [c].[Nullable], [c].[ParentId], [c].[Property]
22+
FROM [ParentEntities] AS [p]
23+
LEFT JOIN [ChildEntities] AS [c] ON [p].[Id] = [c].[ParentId]
24+
WHERE [p].[Id] = 'Guid_1'
25+
ORDER BY [p].[Id]
26+
}
27+
]
28+
}

src/Tests/IntegrationTests/IntegrationTests.cs

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,6 +1487,119 @@ public async Task Parent_child()
14871487
await RunQuery(database, query, null, null, false, new object[] { entity1, entity2, entity3, entity4, entity5 });
14881488
}
14891489

1490+
[Fact]
1491+
public async Task Parent_child_with_id()
1492+
{
1493+
var parent = new ParentEntity
1494+
{
1495+
Property = "Value1"
1496+
};
1497+
var child1 = new ChildEntity
1498+
{
1499+
Property = "Child1",
1500+
Parent = parent
1501+
};
1502+
parent.Children.Add(child1);
1503+
var child2 = new ChildEntity
1504+
{
1505+
Property = "Child2",
1506+
Parent = parent
1507+
};
1508+
parent.Children.Add(child2);
1509+
1510+
var query = $@"
1511+
{{
1512+
parentEntities
1513+
{{
1514+
property
1515+
children(id:'{child1.Id}' )
1516+
{{
1517+
property
1518+
}}
1519+
}}
1520+
}}";
1521+
await using var database = await sqlInstance.Build();
1522+
await RunQuery(database, query, null, null, false, new object[] { parent, child1, child2 });
1523+
}
1524+
1525+
[Fact(Skip = "fix order")]
1526+
public async Task Parent_with_id_child()
1527+
{
1528+
var parent1 = new ParentEntity
1529+
{
1530+
Property = "Value1"
1531+
};
1532+
var parent2 = new ParentEntity
1533+
{
1534+
Property = "Value2"
1535+
};
1536+
var child1 = new ChildEntity
1537+
{
1538+
Property = "Child1",
1539+
Parent = parent1
1540+
};
1541+
parent1.Children.Add(child1);
1542+
var child2 = new ChildEntity
1543+
{
1544+
Property = "Child2",
1545+
Parent = parent1
1546+
};
1547+
parent1.Children.Add(child2);
1548+
1549+
var query = $@"
1550+
{{
1551+
parentEntities(id:'{parent1.Id}')
1552+
{{
1553+
property
1554+
children
1555+
{{
1556+
property
1557+
}}
1558+
}}
1559+
}}";
1560+
await using var database = await sqlInstance.Build();
1561+
await RunQuery(database, query, null, null, false, new object[] { parent1, parent2, child1, child2 });
1562+
}
1563+
1564+
[Fact]
1565+
public async Task Parent_with_id_child_with_id()
1566+
{
1567+
var parent1 = new ParentEntity
1568+
{
1569+
Property = "Value1"
1570+
};
1571+
var parent2 = new ParentEntity
1572+
{
1573+
Property = "Value2"
1574+
};
1575+
var child1 = new ChildEntity
1576+
{
1577+
Property = "Child1",
1578+
Parent = parent1
1579+
};
1580+
parent1.Children.Add(child1);
1581+
var child2 = new ChildEntity
1582+
{
1583+
Property = "Child2",
1584+
Parent = parent1
1585+
};
1586+
parent1.Children.Add(child2);
1587+
1588+
var query = $@"
1589+
{{
1590+
parentEntities(id:'{parent1.Id}')
1591+
{{
1592+
property
1593+
children(id:'{child1.Id}' )
1594+
{{
1595+
property
1596+
}}
1597+
}}
1598+
}}";
1599+
await using var database = await sqlInstance.Build();
1600+
await RunQuery(database, query, null, null, false, new object[] { parent1, parent2, child1, child2 });
1601+
}
1602+
14901603
[Fact]
14911604
public async Task Many_children()
14921605
{

0 commit comments

Comments
 (0)