44using System . Linq ;
55using System . Linq . Expressions ;
66using System . Reflection ;
7+ using System . Runtime . CompilerServices ;
78using LinqToDB . Expressions ;
89using LinqToDB . Reflection ;
910using 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
0 commit comments