-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Query: Enable materialzing collections of arbirtary shape in projection
Part of #15611 Will send out separate PR to enable tests and fix edge case bugs This PR - Split out collection initialization/population for include to separate method due to type constraints - Swallow materialize collection navigation/ToList in projection. Rest of unknown methods, we will fall into client eval - Changes SqlTranslator to try translate & lift subquery always, allowing it to translate non Queryable defined but translatable methods - Make identifiers nullable always to identify null keys & no correlation
- Loading branch information
Showing
16 changed files
with
549 additions
and
317 deletions.
There are no files selected for viewing
65 changes: 65 additions & 0 deletions
65
src/EFCore.Relational/Query/Pipeline/CollectionInitializingExperssion.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System; | ||
using System.Linq.Expressions; | ||
using Microsoft.EntityFrameworkCore.Metadata; | ||
using Microsoft.EntityFrameworkCore.Query.Expressions.Internal; | ||
using Microsoft.EntityFrameworkCore.Query.Internal; | ||
|
||
namespace Microsoft.EntityFrameworkCore.Relational.Query.Pipeline | ||
{ | ||
public class CollectionInitializingExpression : Expression, IPrintable | ||
{ | ||
public CollectionInitializingExpression( | ||
int collectionId, Expression parent, Expression parentIdentifier, Expression outerIdentifier, INavigation navigation, Type type) | ||
{ | ||
CollectionId = collectionId; | ||
Parent = parent; | ||
ParentIdentifier = parentIdentifier; | ||
OuterIdentifier = outerIdentifier; | ||
Navigation = navigation; | ||
Type = type; | ||
} | ||
|
||
protected override Expression VisitChildren(ExpressionVisitor visitor) | ||
{ | ||
var parent = visitor.Visit(Parent); | ||
var parentIdentifier = visitor.Visit(ParentIdentifier); | ||
var outerIdentifier = visitor.Visit(OuterIdentifier); | ||
|
||
return parent != Parent || parentIdentifier != ParentIdentifier || outerIdentifier != OuterIdentifier | ||
? new CollectionInitializingExpression(CollectionId, parent, parentIdentifier, outerIdentifier, Navigation, Type) | ||
: this; | ||
} | ||
|
||
public void Print(ExpressionPrinter expressionPrinter) | ||
{ | ||
expressionPrinter.StringBuilder.AppendLine("InitializeCollection:"); | ||
using (expressionPrinter.StringBuilder.Indent()) | ||
{ | ||
expressionPrinter.StringBuilder.AppendLine($"CollectionId: {CollectionId}"); | ||
expressionPrinter.StringBuilder.AppendLine($"Navigation: {Navigation?.Name}"); | ||
expressionPrinter.StringBuilder.Append("Parent:"); | ||
expressionPrinter.Visit(Parent); | ||
expressionPrinter.StringBuilder.AppendLine(); | ||
expressionPrinter.StringBuilder.Append("ParentIdentifier:"); | ||
expressionPrinter.Visit(ParentIdentifier); | ||
expressionPrinter.StringBuilder.AppendLine(); | ||
expressionPrinter.StringBuilder.Append("OuterIdentifier:"); | ||
expressionPrinter.Visit(OuterIdentifier); | ||
expressionPrinter.StringBuilder.AppendLine(); | ||
} | ||
} | ||
|
||
public override Type Type { get; } | ||
|
||
public override ExpressionType NodeType => ExpressionType.Extension; | ||
|
||
public int CollectionId { get; } | ||
public Expression Parent { get; } | ||
public Expression ParentIdentifier { get; } | ||
public Expression OuterIdentifier { get; } | ||
public INavigation Navigation { get; } | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
src/EFCore.Relational/Query/Pipeline/CollectionPopulatingExpression.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System; | ||
using System.Linq.Expressions; | ||
using Microsoft.EntityFrameworkCore.Query.Expressions.Internal; | ||
using Microsoft.EntityFrameworkCore.Query.Internal; | ||
|
||
namespace Microsoft.EntityFrameworkCore.Relational.Query.Pipeline | ||
{ | ||
public class CollectionPopulatingExpression : Expression, IPrintable | ||
{ | ||
public CollectionPopulatingExpression(RelationalCollectionShaperExpression parent, Type type, bool include) | ||
{ | ||
Parent = parent; | ||
Type = type; | ||
Include = include; | ||
} | ||
|
||
protected override Expression VisitChildren(ExpressionVisitor visitor) | ||
{ | ||
var parent = (RelationalCollectionShaperExpression)visitor.Visit(Parent); | ||
|
||
return parent != Parent | ||
? new CollectionPopulatingExpression(parent, Type, Include) | ||
: this; | ||
} | ||
|
||
public void Print(ExpressionPrinter expressionPrinter) | ||
{ | ||
expressionPrinter.StringBuilder.AppendLine("PopulateCollection:"); | ||
using (expressionPrinter.StringBuilder.Indent()) | ||
{ | ||
expressionPrinter.StringBuilder.Append("Parent:"); | ||
expressionPrinter.Visit(Parent); | ||
} | ||
} | ||
|
||
public override Type Type { get; } | ||
|
||
public override ExpressionType NodeType => ExpressionType.Extension; | ||
public RelationalCollectionShaperExpression Parent { get; } | ||
public bool Include { get; } | ||
} | ||
} |
Oops, something went wrong.