forked from dotnet/efcore
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathShapedQueryExpression.cs
More file actions
143 lines (124 loc) · 6.38 KB
/
Copy pathShapedQueryExpression.cs
File metadata and controls
143 lines (124 loc) · 6.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// 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;
using System.Linq.Expressions;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Utilities;
#nullable enable
namespace Microsoft.EntityFrameworkCore.Query
{
/// <summary>
/// <para>
/// An expression that combines a query expression and shaper expression.
/// </para>
/// <para>
/// This type is typically used by database providers (and other extensions). It is generally
/// not used in application code.
/// </para>
/// </summary>
public class ShapedQueryExpression : Expression, IPrintableExpression
{
/// <summary>
/// Creates a new instance of the <see cref="ShapedQueryExpression" /> class with associated query provider.
/// </summary>
/// <param name="queryExpression"> The query expression to get results from server. </param>
/// <param name="shaperExpression"> The shaper expression to create result objects from server results. </param>
public ShapedQueryExpression([NotNull] Expression queryExpression, [NotNull] Expression shaperExpression)
: this(
Check.NotNull(queryExpression, nameof(queryExpression)),
Check.NotNull(shaperExpression, nameof(shaperExpression)),
ResultCardinality.Enumerable)
{
}
private ShapedQueryExpression(
[NotNull] Expression queryExpression,
[NotNull] Expression shaperExpression,
ResultCardinality resultCardinality)
{
QueryExpression = queryExpression;
ShaperExpression = shaperExpression;
ResultCardinality = resultCardinality;
}
/// <summary>
/// An expression representing the query to be run against server to retrieve the data.
/// </summary>
public virtual Expression QueryExpression { get; }
/// <summary>
/// The cardinality of the results generated.
/// </summary>
public virtual ResultCardinality ResultCardinality { get; }
/// <summary>
/// An expression representing the shaper to be run on the results fetched from the server.
/// </summary>
public virtual Expression ShaperExpression { get; }
/// <inheritdoc />
public override Type Type
=> ResultCardinality == ResultCardinality.Enumerable
? typeof(IQueryable<>).MakeGenericType(ShaperExpression.Type)
: ShaperExpression.Type;
/// <inheritdoc />
public sealed override ExpressionType NodeType
=> ExpressionType.Extension;
/// <inheritdoc />
protected override Expression VisitChildren(ExpressionVisitor visitor)
=> throw new InvalidOperationException(
CoreStrings.VisitIsNotAllowed($"{nameof(ShapedQueryExpression)}.{nameof(VisitChildren)}"));
/// <summary>
/// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will
/// return this expression.
/// </summary>
/// <param name="queryExpression"> The <see cref="QueryExpression" /> property of the result. </param>
/// <param name="shaperExpression"> The <see cref="ShaperExpression" /> property of the result. </param>
/// <returns> This expression if no children changed, or an expression with the updated children. </returns>
public virtual ShapedQueryExpression Update([NotNull] Expression queryExpression, [NotNull] Expression shaperExpression)
{
Check.NotNull(queryExpression, nameof(queryExpression));
Check.NotNull(shaperExpression, nameof(shaperExpression));
return queryExpression != QueryExpression || shaperExpression != ShaperExpression
? new ShapedQueryExpression(queryExpression, shaperExpression, ResultCardinality)
: this;
}
/// <summary>
/// Creates a new expression that is like this one, but using the supplied shaper expression. If shaper expression is the same, it will
/// return this expression.
/// </summary>
/// <param name="shaperExpression"> The <see cref="ShaperExpression" /> property of the result. </param>
/// <returns> This expression if shaper expression did not change, or an expression with the updated shaper expression. </returns>
public virtual ShapedQueryExpression UpdateShaperExpression([NotNull] Expression shaperExpression)
{
Check.NotNull(shaperExpression, nameof(shaperExpression));
return shaperExpression != ShaperExpression
? new ShapedQueryExpression(QueryExpression, shaperExpression, ResultCardinality)
: this;
}
/// <summary>
/// Creates a new expression that is like this one, but with supplied result cardinality.
/// </summary>
/// <param name="resultCardinality"> The <see cref="ResultCardinality" /> property of the result. </param>
/// <returns> An expression with the updated result cardinality. </returns>
public virtual ShapedQueryExpression UpdateResultCardinality(ResultCardinality resultCardinality)
=> new ShapedQueryExpression(QueryExpression, ShaperExpression, resultCardinality);
/// <inheritdoc />
void IPrintableExpression.Print(ExpressionPrinter expressionPrinter)
{
Check.NotNull(expressionPrinter, nameof(expressionPrinter));
expressionPrinter.AppendLine(nameof(ShapedQueryExpression) + ": ");
using (expressionPrinter.Indent())
{
expressionPrinter.AppendLine(nameof(QueryExpression) + ": ");
using (expressionPrinter.Indent())
{
expressionPrinter.Visit(QueryExpression);
}
expressionPrinter.AppendLine().Append(nameof(ShaperExpression) + ": ");
using (expressionPrinter.Indent())
{
expressionPrinter.Visit(ShaperExpression);
}
expressionPrinter.AppendLine();
}
}
}
}