redis / redis-om-dotnet

Object mapping, and more, for Redis and .NET
MIT License
438 stars 71 forks source link

Any not support Contains method #441

Open gruan01 opened 2 months ago

gruan01 commented 2 months ago

Redis.OM version 0.6.1

xxxCollection.Where(h => h.D == date && h.P.Any(pp => bcs.Contains(pp.B))).Take(10).ToListAsync();

throw exception:

  消息: 
    System.InvalidCastException : Unable to cast object of type 'System.Linq.Expressions.MethodCallExpression2' to type 'System.Linq.Expressions.BinaryExpression'.

  堆栈跟踪: 
    ExpressionParserUtilities.TranslateAnyForEmbeddedObjects(MethodCallExpression exp, List`1 parameters)
    ExpressionParserUtilities.TranslateMethodStandardQuerySyntax(MethodCallExpression exp, List`1 parameters)
    ExpressionParserUtilities.GetOperandStringForQueryArgs(Expression exp, List`1 parameters, Boolean treatEnumsAsInt, Boolean negate)
    ExpressionTranslator.TranslateBinaryExpression(BinaryExpression binExpression, List`1 parameters)
    ExpressionTranslator.BuildQueryFromExpression(Expression exp, List`1 parameters)
    ExpressionTranslator.TranslateWhereMethod(MethodCallExpression expression, List`1 parameters)
    ExpressionTranslator.BuildQueryFromExpression(Expression expression, Type type, Expression mainBooleanExpression, Type rootType)
    RedisCollectionEnumerator`1.ctor(Expression exp, IRedisConnection connection, Int32 chunkSize, RedisCollectionStateManager stateManager, Expression`1 booleanExpression, Boolean saveState, Type rootType, Type type)
    RedisCollection`1.GetAsyncEnumerator(CancellationToken cancellationToken)
    RedisCollection`1.ToListAsync()
    RedisIndexTest.SearchTest() 行 147
    --- End of stack trace from previous location ---

if update this method ExpressionParserUtilities.TranslateAnyForEmbeddedObjects like the following can resolve this problem:

        private static string TranslateAnyForEmbeddedObjects(MethodCallExpression exp, List<object> parameters)
        {
            var type = exp.Arguments.Last().Type;
            var prefix = GetOperandString(exp.Arguments[0]);
            var lambda = (LambdaExpression)exp.Arguments.Last();

            if (lambda.Body is MethodCallExpression methodCall)
            {
                var tempQuery = TranslateMethodExpressions(methodCall, parameters);
                return tempQuery.Replace("@", $"{prefix}_");
            }
            else
            {
                var tempQuery = ExpressionTranslator.TranslateBinaryExpression((BinaryExpression)lambda.Body, parameters);
                return tempQuery.Replace("@", $"{prefix}_");
            }
        }
PrudiusVladislav commented 3 weeks ago

It seems like the problem persists in Redis.OM 0.7.0, as I also ran into the same issue. Have you thought about opening a PR?