Skip to content

Commit 737f8e2

Browse files
authored
Query: Add support for non entity query roots (#28472)
Part of #11624
1 parent c54353c commit 737f8e2

File tree

32 files changed

+216
-131
lines changed

32 files changed

+216
-131
lines changed

src/EFCore.Cosmos/Extensions/CosmosQueryableExtensions.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -86,17 +86,17 @@ public static IQueryable<TEntity> FromSqlRaw<TEntity>(
8686
Check.NotNull(parameters, nameof(parameters));
8787

8888
var queryableSource = (IQueryable)source;
89-
var queryRootExpression = (QueryRootExpression)queryableSource.Expression;
89+
var entityQueryRootExpression = (EntityQueryRootExpression)queryableSource.Expression;
9090

91-
var entityType = queryRootExpression.EntityType;
91+
var entityType = entityQueryRootExpression.EntityType;
9292

9393
Check.DebugAssert(
9494
(entityType.BaseType is null && !entityType.GetDirectlyDerivedTypes().Any())
9595
|| entityType.FindDiscriminatorProperty() is not null,
9696
"Found FromSql on a TPT entity type, but TPT isn't supported on Cosmos");
9797

9898
var fromSqlQueryRootExpression = new FromSqlQueryRootExpression(
99-
queryRootExpression.QueryProvider!,
99+
entityQueryRootExpression.QueryProvider!,
100100
entityType,
101101
sql,
102102
Expression.Constant(parameters));

src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,9 @@ public override Expression Visit(Expression expression)
8686
&& methodCallExpression.Method.IsGenericMethod
8787
&& queryRootMethodCallExpression.Method.GetGenericMethodDefinition() == QueryableMethods.Where)
8888
{
89-
if (queryRootMethodCallExpression.Arguments[0] is QueryRootExpression queryRootExpression)
89+
if (queryRootMethodCallExpression.Arguments[0] is EntityQueryRootExpression entityQueryRootExpression)
9090
{
91-
var entityType = queryRootExpression.EntityType;
91+
var entityType = entityQueryRootExpression.EntityType;
9292

9393
if (queryRootMethodCallExpression.Arguments[1] is UnaryExpression unaryExpression
9494
&& unaryExpression.Operand is LambdaExpression lambdaExpression)

src/EFCore.Cosmos/Query/Internal/FromSqlQueryRootExpression.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
99
/// any release. You should only use it directly in your code with extreme caution and knowing that
1010
/// doing so can result in application failures when updating to a new Entity Framework Core release.
1111
/// </summary>
12-
public class FromSqlQueryRootExpression : QueryRootExpression
12+
public class FromSqlQueryRootExpression : EntityQueryRootExpression
1313
{
1414
/// <summary>
1515
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -75,7 +75,7 @@ public override Expression DetachQueryProvider()
7575
/// any release. You should only use it directly in your code with extreme caution and knowing that
7676
/// doing so can result in application failures when updating to a new Entity Framework Core release.
7777
/// </summary>
78-
public override QueryRootExpression UpdateEntityType(IEntityType entityType)
78+
public override EntityQueryRootExpression UpdateEntityType(IEntityType entityType)
7979
=> entityType.ClrType != EntityType.ClrType
8080
|| entityType.Name != EntityType.Name
8181
? throw new InvalidOperationException(CoreStrings.QueryRootDifferentEntityType(entityType.DisplayName()))

src/EFCore.InMemory/Metadata/Conventions/DefiningQueryRewritingConvention.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Conventions;
55

66
/// <summary>
77
/// Convention that converts accesses of <see cref="DbSet{TEntity}" /> inside query filters and defining queries into
8-
/// <see cref="QueryRootExpression" />.
8+
/// <see cref="EntityQueryRootExpression" />.
99
/// This makes them consistent with how DbSet accesses in the actual queries are represented, which allows for easier processing in the
1010
/// query pipeline.
1111
/// </summary>

src/EFCore.Relational/Extensions/RelationalQueryableExtensions.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -146,17 +146,17 @@ private static FromSqlQueryRootExpression GenerateFromSqlQueryRoot(
146146
object?[] arguments,
147147
[CallerMemberName] string memberName = null!)
148148
{
149-
var queryRootExpression = (QueryRootExpression)source.Expression;
149+
var entityQueryRootExpression = (EntityQueryRootExpression)source.Expression;
150150

151-
var entityType = queryRootExpression.EntityType;
151+
var entityType = entityQueryRootExpression.EntityType;
152152
if ((entityType.BaseType != null || entityType.GetDirectlyDerivedTypes().Any())
153153
&& entityType.FindDiscriminatorProperty() == null)
154154
{
155155
throw new InvalidOperationException(RelationalStrings.MethodOnNonTphRootNotSupported(memberName, entityType.DisplayName()));
156156
}
157157

158158
return new FromSqlQueryRootExpression(
159-
queryRootExpression.QueryProvider!,
159+
entityQueryRootExpression.QueryProvider!,
160160
entityType,
161161
sql,
162162
Expression.Constant(arguments));

src/EFCore.Relational/Metadata/Conventions/RelationalQueryFilterRewritingConvention.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
7070
&& (methodName == nameof(RelationalQueryableExtensions.FromSqlRaw)
7171
|| methodName == nameof(RelationalQueryableExtensions.FromSqlInterpolated)))
7272
{
73-
var newSource = (QueryRootExpression)Visit(methodCallExpression.Arguments[0]);
73+
var newSource = (EntityQueryRootExpression)Visit(methodCallExpression.Arguments[0]);
7474

7575
string sql;
7676
Expression argument;

src/EFCore.Relational/Query/Internal/FromSqlQueryRootExpression.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Microsoft.EntityFrameworkCore.Query.Internal;
99
/// any release. You should only use it directly in your code with extreme caution and knowing that
1010
/// doing so can result in application failures when updating to a new Entity Framework Core release.
1111
/// </summary>
12-
public sealed class FromSqlQueryRootExpression : QueryRootExpression
12+
public sealed class FromSqlQueryRootExpression : EntityQueryRootExpression
1313
{
1414
/// <summary>
1515
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -75,7 +75,7 @@ public override Expression DetachQueryProvider()
7575
/// any release. You should only use it directly in your code with extreme caution and knowing that
7676
/// doing so can result in application failures when updating to a new Entity Framework Core release.
7777
/// </summary>
78-
public override QueryRootExpression UpdateEntityType(IEntityType entityType)
78+
public override EntityQueryRootExpression UpdateEntityType(IEntityType entityType)
7979
=> entityType.ClrType != EntityType.ClrType
8080
|| entityType.Name != EntityType.Name
8181
? throw new InvalidOperationException(CoreStrings.QueryRootDifferentEntityType(entityType.DisplayName()))

src/EFCore.Relational/Query/Internal/TableValuedFunctionQueryRootExpression.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Microsoft.EntityFrameworkCore.Query.Internal;
99
/// any release. You should only use it directly in your code with extreme caution and knowing that
1010
/// doing so can result in application failures when updating to a new Entity Framework Core release.
1111
/// </summary>
12-
public sealed class TableValuedFunctionQueryRootExpression : QueryRootExpression
12+
public sealed class TableValuedFunctionQueryRootExpression : EntityQueryRootExpression
1313
{
1414
/// <summary>
1515
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -72,7 +72,7 @@ protected override Expression VisitChildren(ExpressionVisitor visitor)
7272
/// any release. You should only use it directly in your code with extreme caution and knowing that
7373
/// doing so can result in application failures when updating to a new Entity Framework Core release.
7474
/// </summary>
75-
public override QueryRootExpression UpdateEntityType(IEntityType entityType)
75+
public override EntityQueryRootExpression UpdateEntityType(IEntityType entityType)
7676
=> entityType.ClrType != EntityType.ClrType
7777
|| entityType.Name != EntityType.Name
7878
? throw new InvalidOperationException(CoreStrings.QueryRootDifferentEntityType(entityType.DisplayName()))

src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs

+6-6
Original file line numberDiff line numberDiff line change
@@ -122,16 +122,16 @@ protected override Expression VisitExtension(Expression extensionExpression)
122122

123123
return CreateShapedQueryExpression(entityType, queryExpression);
124124

125-
case QueryRootExpression queryRootExpression
126-
when queryRootExpression.GetType() == typeof(QueryRootExpression)
127-
&& queryRootExpression.EntityType.GetSqlQueryMappings().FirstOrDefault(m => m.IsDefaultSqlQueryMapping)?.SqlQuery is
125+
case EntityQueryRootExpression entityQueryRootExpression
126+
when entityQueryRootExpression.GetType() == typeof(EntityQueryRootExpression)
127+
&& entityQueryRootExpression.EntityType.GetSqlQueryMappings().FirstOrDefault(m => m.IsDefaultSqlQueryMapping)?.SqlQuery is
128128
ISqlQuery sqlQuery:
129129
return CreateShapedQueryExpression(
130-
queryRootExpression.EntityType,
130+
entityQueryRootExpression.EntityType,
131131
_sqlExpressionFactory.Select(
132-
queryRootExpression.EntityType,
132+
entityQueryRootExpression.EntityType,
133133
new FromSqlExpression(
134-
queryRootExpression.EntityType.GetDefaultMappings().Single().Table,
134+
entityQueryRootExpression.EntityType.GetDefaultMappings().Single().Table,
135135
sqlQuery.Sql,
136136
Expression.Constant(Array.Empty<object>(), typeof(object[])))));
137137

src/EFCore.SqlServer/Extensions/SqlServerDbSetExtensions.cs

+15-15
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@ public static IQueryable<TEntity> TemporalAsOf<TEntity>(
3737
where TEntity : class
3838
{
3939
var queryableSource = (IQueryable)source;
40-
var queryRootExpression = (QueryRootExpression)queryableSource.Expression;
41-
var entityType = queryRootExpression.EntityType;
40+
var entityQueryRootExpression = (EntityQueryRootExpression)queryableSource.Expression;
41+
var entityType = entityQueryRootExpression.EntityType;
4242

4343
return queryableSource.Provider.CreateQuery<TEntity>(
4444
new TemporalAsOfQueryRootExpression(
45-
queryRootExpression.QueryProvider!,
45+
entityQueryRootExpression.QueryProvider!,
4646
entityType,
4747
utcPointInTime)).AsNoTracking();
4848
}
@@ -83,12 +83,12 @@ public static IQueryable<TEntity> TemporalFromTo<TEntity>(
8383
where TEntity : class
8484
{
8585
var queryableSource = (IQueryable)source;
86-
var queryRootExpression = (QueryRootExpression)queryableSource.Expression;
87-
var entityType = queryRootExpression.EntityType;
86+
var entityQueryRootExpression = (EntityQueryRootExpression)queryableSource.Expression;
87+
var entityType = entityQueryRootExpression.EntityType;
8888

8989
return queryableSource.Provider.CreateQuery<TEntity>(
9090
new TemporalFromToQueryRootExpression(
91-
queryRootExpression.QueryProvider!,
91+
entityQueryRootExpression.QueryProvider!,
9292
entityType,
9393
utcFrom,
9494
utcTo)).AsNoTracking();
@@ -130,12 +130,12 @@ public static IQueryable<TEntity> TemporalBetween<TEntity>(
130130
where TEntity : class
131131
{
132132
var queryableSource = (IQueryable)source;
133-
var queryRootExpression = (QueryRootExpression)queryableSource.Expression;
134-
var entityType = queryRootExpression.EntityType;
133+
var entityQueryRootExpression = (EntityQueryRootExpression)queryableSource.Expression;
134+
var entityType = entityQueryRootExpression.EntityType;
135135

136136
return queryableSource.Provider.CreateQuery<TEntity>(
137137
new TemporalBetweenQueryRootExpression(
138-
queryRootExpression.QueryProvider!,
138+
entityQueryRootExpression.QueryProvider!,
139139
entityType,
140140
utcFrom,
141141
utcTo)).AsNoTracking();
@@ -177,12 +177,12 @@ public static IQueryable<TEntity> TemporalContainedIn<TEntity>(
177177
where TEntity : class
178178
{
179179
var queryableSource = (IQueryable)source;
180-
var queryRootExpression = (QueryRootExpression)queryableSource.Expression;
181-
var entityType = queryRootExpression.EntityType;
180+
var entityQueryRootExpression = (EntityQueryRootExpression)queryableSource.Expression;
181+
var entityType = entityQueryRootExpression.EntityType;
182182

183183
return queryableSource.Provider.CreateQuery<TEntity>(
184184
new TemporalContainedInQueryRootExpression(
185-
queryRootExpression.QueryProvider!,
185+
entityQueryRootExpression.QueryProvider!,
186186
entityType,
187187
utcFrom,
188188
utcTo)).AsNoTracking();
@@ -208,11 +208,11 @@ public static IQueryable<TEntity> TemporalAll<TEntity>(
208208
where TEntity : class
209209
{
210210
var queryableSource = (IQueryable)source;
211-
var queryRootExpression = (QueryRootExpression)queryableSource.Expression;
212-
var entityType = queryRootExpression.EntityType;
211+
var entityQueryRootExpression = (EntityQueryRootExpression)queryableSource.Expression;
212+
var entityType = entityQueryRootExpression.EntityType;
213213

214214
return queryableSource.Provider.CreateQuery<TEntity>(
215215
new TemporalAllQueryRootExpression(
216-
queryRootExpression.QueryProvider!, entityType)).AsNoTracking();
216+
entityQueryRootExpression.QueryProvider!, entityType)).AsNoTracking();
217217
}
218218
}

src/EFCore.SqlServer/Query/Internal/SqlServerNavigationExpansionExtensibilityHelper.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public SqlServerNavigationExpansionExtensibilityHelper(NavigationExpansionExtens
3030
/// any release. You should only use it directly in your code with extreme caution and knowing that
3131
/// doing so can result in application failures when updating to a new Entity Framework Core release.
3232
/// </summary>
33-
public override QueryRootExpression CreateQueryRoot(IEntityType entityType, QueryRootExpression? source)
33+
public override EntityQueryRootExpression CreateQueryRoot(IEntityType entityType, EntityQueryRootExpression? source)
3434
{
3535
if (source is TemporalAsOfQueryRootExpression asOf)
3636
{
@@ -49,7 +49,7 @@ public override QueryRootExpression CreateQueryRoot(IEntityType entityType, Quer
4949
/// any release. You should only use it directly in your code with extreme caution and knowing that
5050
/// doing so can result in application failures when updating to a new Entity Framework Core release.
5151
/// </summary>
52-
public override void ValidateQueryRootCreation(IEntityType entityType, QueryRootExpression? source)
52+
public override void ValidateQueryRootCreation(IEntityType entityType, EntityQueryRootExpression? source)
5353
{
5454
if (source is TemporalQueryRootExpression)
5555
{
@@ -75,7 +75,7 @@ public override void ValidateQueryRootCreation(IEntityType entityType, QueryRoot
7575
/// any release. You should only use it directly in your code with extreme caution and knowing that
7676
/// doing so can result in application failures when updating to a new Entity Framework Core release.
7777
/// </summary>
78-
public override bool AreQueryRootsCompatible(QueryRootExpression? first, QueryRootExpression? second)
78+
public override bool AreQueryRootsCompatible(EntityQueryRootExpression? first, EntityQueryRootExpression? second)
7979
{
8080
if (!base.AreQueryRootsCompatible(first, second))
8181
{

src/EFCore.SqlServer/Query/Internal/TemporalAllQueryRootExpression.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public override Expression DetachQueryProvider()
4848
/// any release. You should only use it directly in your code with extreme caution and knowing that
4949
/// doing so can result in application failures when updating to a new Entity Framework Core release.
5050
/// </summary>
51-
public override QueryRootExpression UpdateEntityType(IEntityType entityType)
51+
public override EntityQueryRootExpression UpdateEntityType(IEntityType entityType)
5252
=> entityType.ClrType != EntityType.ClrType
5353
|| entityType.Name != EntityType.Name
5454
? throw new InvalidOperationException(CoreStrings.QueryRootDifferentEntityType(entityType.DisplayName()))

src/EFCore.SqlServer/Query/Internal/TemporalAsOfQueryRootExpression.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public override Expression DetachQueryProvider()
6161
/// any release. You should only use it directly in your code with extreme caution and knowing that
6262
/// doing so can result in application failures when updating to a new Entity Framework Core release.
6363
/// </summary>
64-
public override QueryRootExpression UpdateEntityType(IEntityType entityType)
64+
public override EntityQueryRootExpression UpdateEntityType(IEntityType entityType)
6565
=> entityType.ClrType != EntityType.ClrType
6666
|| entityType.Name != EntityType.Name
6767
? throw new InvalidOperationException(CoreStrings.QueryRootDifferentEntityType(entityType.DisplayName()))

src/EFCore.SqlServer/Query/Internal/TemporalBetweenQueryRootExpression.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public override Expression DetachQueryProvider()
5555
/// any release. You should only use it directly in your code with extreme caution and knowing that
5656
/// doing so can result in application failures when updating to a new Entity Framework Core release.
5757
/// </summary>
58-
public override QueryRootExpression UpdateEntityType(IEntityType entityType)
58+
public override EntityQueryRootExpression UpdateEntityType(IEntityType entityType)
5959
=> entityType.ClrType != EntityType.ClrType
6060
|| entityType.Name != EntityType.Name
6161
? throw new InvalidOperationException(CoreStrings.QueryRootDifferentEntityType(entityType.DisplayName()))

src/EFCore.SqlServer/Query/Internal/TemporalContainedInQueryRootExpression.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public override Expression DetachQueryProvider()
5555
/// any release. You should only use it directly in your code with extreme caution and knowing that
5656
/// doing so can result in application failures when updating to a new Entity Framework Core release.
5757
/// </summary>
58-
public override QueryRootExpression UpdateEntityType(IEntityType entityType)
58+
public override EntityQueryRootExpression UpdateEntityType(IEntityType entityType)
5959
=> entityType.ClrType != EntityType.ClrType
6060
|| entityType.Name != EntityType.Name
6161
? throw new InvalidOperationException(CoreStrings.QueryRootDifferentEntityType(entityType.DisplayName()))

src/EFCore.SqlServer/Query/Internal/TemporalFromToQueryRootExpression.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public override Expression DetachQueryProvider()
5555
/// any release. You should only use it directly in your code with extreme caution and knowing that
5656
/// doing so can result in application failures when updating to a new Entity Framework Core release.
5757
/// </summary>
58-
public override QueryRootExpression UpdateEntityType(IEntityType entityType)
58+
public override EntityQueryRootExpression UpdateEntityType(IEntityType entityType)
5959
=> entityType.ClrType != EntityType.ClrType
6060
|| entityType.Name != EntityType.Name
6161
? throw new InvalidOperationException(CoreStrings.QueryRootDifferentEntityType(entityType.DisplayName()))

src/EFCore.SqlServer/Query/Internal/TemporalQueryRootExpression.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal;
99
/// any release. You should only use it directly in your code with extreme caution and knowing that
1010
/// doing so can result in application failures when updating to a new Entity Framework Core release.
1111
/// </summary>
12-
public abstract class TemporalQueryRootExpression : QueryRootExpression
12+
public abstract class TemporalQueryRootExpression : EntityQueryRootExpression
1313
{
1414
/// <summary>
1515
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to

0 commit comments

Comments
 (0)