-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update SearchCondition visitor with improvements from SQL Server vers…
…ion (#255) * Update SearchCondition visitor with improvements from SQL Server version
- Loading branch information
1 parent
8a5c4d8
commit bf6e8a1
Showing
13 changed files
with
954 additions
and
851 deletions.
There are no files selected for viewing
1,070 changes: 511 additions & 559 deletions
1,070
src/EFCore.Jet/Query/Internal/SearchConditionConvertingExpressionVisitor.cs
Large diffs are not rendered by default.
Oops, something went wrong.
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,130 @@ | ||
using Microsoft.EntityFrameworkCore.Diagnostics; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
// ReSharper disable once CheckNamespace | ||
using System.Runtime.CompilerServices; | ||
|
||
namespace System.Linq.Expressions; | ||
|
||
#nullable enable | ||
|
||
[DebuggerStepThrough] | ||
internal static class ExpressionVisitorExtensions | ||
{ | ||
/// <summary> | ||
/// Dispatches the list of expressions to one of the more specialized visit methods in this class. | ||
/// </summary> | ||
/// <param name="visitor">The expression visitor.</param> | ||
/// <param name="nodes">The expressions to visit.</param> | ||
/// <returns> | ||
/// The modified expression list, if any of the elements were modified; otherwise, returns the original expression list. | ||
/// </returns> | ||
public static IReadOnlyList<Expression> Visit(this ExpressionVisitor visitor, IReadOnlyList<Expression> nodes) | ||
{ | ||
Expression[]? newNodes = null; | ||
for (int i = 0, n = nodes.Count; i < n; i++) | ||
{ | ||
var node = visitor.Visit(nodes[i]); | ||
|
||
if (newNodes is not null) | ||
{ | ||
newNodes[i] = node; | ||
} | ||
else if (!ReferenceEquals(node, nodes[i])) | ||
{ | ||
newNodes = new Expression[n]; | ||
for (var j = 0; j < i; j++) | ||
{ | ||
newNodes[j] = nodes[j]; | ||
} | ||
|
||
newNodes[i] = node; | ||
} | ||
} | ||
|
||
return newNodes ?? nodes; | ||
} | ||
|
||
/// <summary> | ||
/// Visits an expression, casting the result back to the original expression type. | ||
/// </summary> | ||
/// <typeparam name="T">The type of the expression.</typeparam> | ||
/// <param name="visitor">The expression visitor.</param> | ||
/// <param name="nodes">The expression to visit.</param> | ||
/// <param name="callerName">The name of the calling method; used to report to report a better error message.</param> | ||
/// <returns> | ||
/// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. | ||
/// </returns> | ||
/// <exception cref="InvalidOperationException">The visit method for this node returned a different type.</exception> | ||
public static IReadOnlyList<T> VisitAndConvert<T>( | ||
this ExpressionVisitor visitor, | ||
IReadOnlyList<T> nodes, | ||
[CallerMemberName] string? callerName = null) | ||
where T : Expression | ||
{ | ||
T[]? newNodes = null; | ||
for (int i = 0, n = nodes.Count; i < n; i++) | ||
{ | ||
if (visitor.Visit(nodes[i]) is not T node) | ||
{ | ||
throw new InvalidOperationException(CoreStrings.MustRewriteToSameNode(callerName, typeof(T).Name)); | ||
} | ||
|
||
if (newNodes is not null) | ||
{ | ||
newNodes[i] = node; | ||
} | ||
else if (!ReferenceEquals(node, nodes[i])) | ||
{ | ||
newNodes = new T[n]; | ||
for (var j = 0; j < i; j++) | ||
{ | ||
newNodes[j] = nodes[j]; | ||
} | ||
|
||
newNodes[i] = node; | ||
} | ||
} | ||
|
||
return newNodes ?? nodes; | ||
} | ||
|
||
/// <summary> | ||
/// Visits all nodes in the collection using a specified element visitor. | ||
/// </summary> | ||
/// <typeparam name="T">The type of the nodes.</typeparam> | ||
/// <param name="visitor">The expression visitor.</param> | ||
/// <param name="nodes">The nodes to visit.</param> | ||
/// <param name="elementVisitor"> | ||
/// A delegate that visits a single element, | ||
/// optionally replacing it with a new element. | ||
/// </param> | ||
/// <returns> | ||
/// The modified node list, if any of the elements were modified; | ||
/// otherwise, returns the original node list. | ||
/// </returns> | ||
public static IReadOnlyList<T> Visit<T>(this ExpressionVisitor visitor, IReadOnlyList<T> nodes, Func<T, T> elementVisitor) | ||
{ | ||
T[]? newNodes = null; | ||
for (int i = 0, n = nodes.Count; i < n; i++) | ||
{ | ||
var node = elementVisitor(nodes[i]); | ||
if (newNodes is not null) | ||
{ | ||
newNodes[i] = node; | ||
} | ||
else if (!ReferenceEquals(node, nodes[i])) | ||
{ | ||
newNodes = new T[n]; | ||
for (var j = 0; j < i; j++) | ||
{ | ||
newNodes[j] = nodes[j]; | ||
} | ||
|
||
newNodes[i] = node; | ||
} | ||
} | ||
|
||
return newNodes ?? nodes; | ||
} | ||
} |
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
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
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
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
Oops, something went wrong.