1

如何将其包装成可重用的表达式,以便在代码的其他地方使用?

nv => nv.a == nv2.a

我试过这样做,但似乎返回 aConstantExpression而不是 a LambdaExpression

public Func<EntityName, bool> compareExpression()
{
    return nv => nv.a == this.a;
}

我不介意我是如何做到这一点的,只要我有一个 LambdaExpression,我可以在代码中的多个地方使用它。DB 驱动程序将读取表达式并将其转换。

更多详情

鉴于这种;

db.p.insert(
  {
    arrayNest: [
      { a:1, b:10 },
      { a:2, b:20 },
      { a:3, b:30 },
      { a:4, b:40 },
]
  }
);

class NV {
    int a;
    int b;
    public Func<EntityName, bool> compareExpression()
    {
        return nv => nv.a == this.a;
    }
}
class P {
     NV[] arrayNest;
}

和一个方法;

    public virtual void Delete(Expression<Func<T, bool>> criteria)
    {
        this.Collection.Remove(Query<T>.Where(criteria));
    }

    var nv2 = new NV();
    Delete(p => p.arrayNest.Any(nv => nv.a == nv2.a)); // Works fine

但是,当我使用返回表达式的函数中的 lambda 时;

    Delete(p => p.arrayNest.Any(nv => nv2.compareExpression())); // FAILS

我得到一个

 System.InvalidCastException: Unable to cast object of type 'System.Linq.Expressions.ConstantExpression' to type 'System.Linq.Expressions.LambdaExpression'.

 Result StackTrace: 
  at MongoDB.Driver.Linq.PredicateTranslator.BuildAnyQuery(MethodCallExpression methodCallExpression)  

我看到MongoDB.Driver.Linq.PredicateTranslator假设每个表达式都是(LambdaExpression).

那么这是驱动程序问题,还是我做错了什么?奇怪的是我根本不明白它为什么要评估为一个 ConstantExpression。

4

1 回答 1

0

问题是您的compareExpression方法返回一个表达式而不是该Any方法正在寻找的布尔值。您可以像这样调用返回的表达式compareExpression

Delete(p => p.arrayNest.Any(nv => nv.compareExpression().Invoke(nv)));

但是你compareExpression编写传入的对象的方式与对象compareExpression相同this,所以它总是会返回true。

于 2012-10-26T07:15:32.200 回答