Skip to content
This repository was archived by the owner on Feb 1, 2025. It is now read-only.

Commit 0394c3f

Browse files
authored
Fixed found issues with integration. (#91)
* Fixed found problems with query translation. * Removed obsolete functionality. * Added regression test for #88.
1 parent 769e319 commit 0394c3f

File tree

16 files changed

+286
-378
lines changed

16 files changed

+286
-378
lines changed

Source/LinqToDB.EntityFrameworkCore/EFCoreMetadataReader.cs

Lines changed: 103 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Linq;
55
using System.Linq.Expressions;
66
using System.Reflection;
7+
using System.Runtime.CompilerServices;
78
using LinqToDB.Expressions;
89
using LinqToDB.Reflection;
910
using Microsoft.EntityFrameworkCore;
@@ -67,19 +68,12 @@ public T[] GetAttributes<T>(Type type, bool inherit = true) where T : Attribute
6768
var contextProp = Expression.Property(Expression.Convert(dcParam, typeof(LinqToDBForEFToolsDataConnection)), "Context");
6869
var filterBody = filter.Body.Transform(e =>
6970
{
70-
switch (e)
71+
if (typeof(DbContext).IsSameOrParentOf(e.Type))
7172
{
72-
case ConstantExpression cnt:
73-
{
74-
if (typeof(DbContext).IsSameOrParentOf(cnt.Type))
75-
{
76-
Expression newExpr = contextProp;
77-
if (newExpr.Type != cnt.Type)
78-
newExpr = Expression.Convert(newExpr, cnt.Type);
79-
return newExpr;
80-
}
81-
break;
82-
}
73+
Expression newExpr = contextProp;
74+
if (newExpr.Type != e.Type)
75+
newExpr = Expression.Convert(newExpr, e.Type);
76+
return newExpr;
8377
}
8478

8579
return e;
@@ -323,6 +317,24 @@ protected override void Print(ExpressionPrinter expressionPrinter)
323317
{
324318
expressionPrinter.Print(Expression);
325319
}
320+
321+
protected bool Equals(SqlTransparentExpression other)
322+
{
323+
return ReferenceEquals(this, other);
324+
}
325+
326+
public override bool Equals(object obj)
327+
{
328+
if (ReferenceEquals(null, obj)) return false;
329+
if (ReferenceEquals(this, obj)) return true;
330+
if (obj.GetType() != this.GetType()) return false;
331+
return Equals((SqlTransparentExpression) obj);
332+
}
333+
334+
public override int GetHashCode()
335+
{
336+
return RuntimeHelpers.GetHashCode(this);
337+
}
326338
}
327339

328340
private Sql.ExpressionAttribute? GetDbFunctionFromMethodCall(Type type, MethodInfo methodInfo)
@@ -399,7 +411,32 @@ private static EFCoreExpressionAttribute ConvertToExpressionAttribute(MemberInfo
399411
{
400412
string PrepareExpressionText(Expression? expr)
401413
{
402-
var idx = Array.IndexOf(parameters, expr);
414+
var idx = -1;
415+
416+
for (var index = 0; index < parameters.Length; index++)
417+
{
418+
var param = parameters[index];
419+
var found = ReferenceEquals(expr, param);
420+
if (!found)
421+
{
422+
if (param is SqlTransparentExpression transparent)
423+
{
424+
if (transparent.Expression is ConstantExpression constantExpr &&
425+
expr is SqlConstantExpression sqlConstantExpr)
426+
{
427+
//found = sqlConstantExpr.Value.Equals(constantExpr.Value);
428+
found = true;
429+
}
430+
}
431+
}
432+
433+
if (found)
434+
{
435+
idx = index;
436+
break;
437+
}
438+
}
439+
403440
if (idx >= 0)
404441
return $"{{{idx}}}";
405442

@@ -429,18 +466,63 @@ string PrepareExpressionText(Expression? expr)
429466
return text;
430467
}
431468

432-
if (newExpression.GetType().GetProperty("Left") != null &&
433-
newExpression.GetType().GetProperty("Right") != null &&
434-
newExpression.GetType().GetProperty("Operator") != null)
469+
if (newExpression.GetType().Name == "PostgresBinaryExpression")
435470
{
436-
// Handling NpgSql's CustomBinaryExpression
471+
// Handling NpgSql's PostgresBinaryExpression
437472

438-
var left = newExpression.GetType().GetProperty("Left")?.GetValue(newExpression) as Expression;
473+
var left = newExpression.GetType().GetProperty("Left")?.GetValue(newExpression) as Expression;
439474
var right = newExpression.GetType().GetProperty("Right")?.GetValue(newExpression) as Expression;
440475

441-
var operand = newExpression.GetType().GetProperty("Operator")?.GetValue(newExpression) as string;
476+
var operand = newExpression.GetType().GetProperty("OperatorType")?.GetValue(newExpression).ToString();
477+
478+
var operandExpr = operand;
479+
480+
operandExpr = operand switch
481+
{
482+
"Contains"
483+
when left!.Type.Name == "NpgsqlInetTypeMapping" ||
484+
left.Type.Name == "NpgsqlCidrTypeMapping"
485+
=> ">>",
486+
"ContainedBy"
487+
when left!.Type.Name == "NpgsqlInetTypeMapping" ||
488+
left.Type.Name == "NpgsqlCidrTypeMapping"
489+
=> "<<",
490+
"Contains" => "@>",
491+
"ContainedBy" => "<@",
492+
"Overlaps" => "&&",
493+
"AtTimeZone" => "AT TIME ZONE",
494+
"NetworkContainedByOrEqual" => "<<=",
495+
"NetworkContainsOrEqual" => ">>=",
496+
"NetworkContainsOrContainedBy" => "&&",
497+
"RangeIsStrictlyLeftOf" => "<<",
498+
"RangeIsStrictlyRightOf" => ">>",
499+
"RangeDoesNotExtendRightOf" => "&<",
500+
"RangeDoesNotExtendLeftOf" => "&>",
501+
"RangeIsAdjacentTo" => "-|-",
502+
"RangeUnion" => "+",
503+
"RangeIntersect" => "*",
504+
"RangeExcept" => "-",
505+
"TextSearchMatch" => "@@",
506+
"TextSearchAnd" => "&&",
507+
"TextSearchOr" => "||",
508+
"JsonExists" => "?",
509+
"JsonExistsAny" => "?|",
510+
"JsonExistsAll" => "?&",
511+
_ => throw new InvalidOperationException(
512+
$"Unknown PostgresBinaryExpression.OperatorType: '{operand}'")
513+
};
514+
515+
switch (operand)
516+
{
517+
case "Contains":
518+
operandExpr = "@>"; break;
519+
case "ContainedBy":
520+
operandExpr = "<@"; break;
521+
case "Overlaps":
522+
operandExpr = "&&"; break;
523+
}
442524

443-
var text = $"{PrepareExpressionText(left)} {operand} {PrepareExpressionText(right)}";
525+
var text = $"{PrepareExpressionText(left)} {operandExpr} {PrepareExpressionText(right)}";
444526

445527
return text;
446528
}
@@ -464,7 +546,7 @@ private static Expression UnwrapConverted(Expression expr)
464546
if (expr is SqlFunctionExpression func)
465547
{
466548
if (string.Equals(func.Name, "COALESCE", StringComparison.InvariantCultureIgnoreCase) &&
467-
func.Arguments.Count == 2 && func.Arguments[1].NodeType == ExpressionType.Default)
549+
func.Arguments.Count == 2 && func.Arguments[1].NodeType == ExpressionType.Extension)
468550
return UnwrapConverted(func.Arguments[0]);
469551
}
470552

Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFTools.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,6 @@ static bool InitializeInternal()
7878

7979
LinqExtensions.ExtensionsAdapter = new LinqToDBExtensionsAdapter();
8080

81-
// Set linq2db to allow multiple queries by default
82-
Common.Configuration.Linq.AllowMultipleQuery = true;
83-
8481
return true;
8582
}
8683

0 commit comments

Comments
 (0)