【问题标题】:Query with triple selector使用三重选择器查询
【发布时间】:2012-10-01 18:37:51
【问题描述】:

我目前有 Lambda 表达式:http://pastebin.com/ZGCiQdHe

我在 53 行得到 ArgumentException http://msdn.microsoft.com/en-us/library/bb340145(v=vs.90).aspx

var lExpresion = Expression.Lambda<Func<TEntity, bool>>(body, parametrsNumber, parametrsTyp, parametrsLp);

但我不明白我做错了什么。

我想得到:

    WHERE ((twr_gidnumer =1 and twr_gidtyp = 1 and twr_gidlp = 1) OR 
    (twr_gidnumer =1 and twr_gidtyp = 1 and twr_gidlp = 2))

--完整回答

根据文章:

http://blogs.msdn.com/b/mattwar/archive/2007/07/31/linq-building-an-iqueryable-provider-part-ii.aspx https://stackoverflow.com/Converting 2 argument Lambda expression to 1 argument Lambda expression

public static Expression<Func<CDNXL_TwrKarty, bool>> Bind2nd(Expression<Func<CDNXL_TwrKarty, CDNXL_TwrKarty,CDNXL_TwrKarty, bool>> source)
{
    Expression newBody = new Rewriter(source.Parameters[0]).Visit(source.Body);
    return Expression.Lambda<Func<CDNXL_TwrKarty, bool>>(newBody, source.Parameters[0]);
}

internal class Rewriter : ExpressionVisitor
{
    private readonly ParameterExpression candidate_;

    public Rewriter(ParameterExpression candidate)
    {
        candidate_ = candidate;
    }

    protected override Expression VisitParameter(ParameterExpression p)
    {
        return candidate_;
    }
}
//REPLACE EXECUTING PLACE
var retMultiLamnda = Expression.Lambda<Func<CDNXL_TwrKarty, CDNXL_TwrKarty, CDNXL_TwrKarty, bool>>(body, parametrsNumber, parametrsTyp, parametrsLp);
var retOneLambda = Bind2nd(retMultiLamnda);
var retQuery = query.Where(retOneLambda);
return retQuery;

感谢Rafal 的帮助。

【问题讨论】:

  • ExprssionVisitor 很高兴拥有 +1

标签: c# entity-framework .net-3.5 lambda


【解决方案1】:

我看到的第一件事是您的委托类型与您的调用列表不匹配。您希望创建一个接收TEntity 类型参数的函数,但您将树形参数表达式传递给函数。请注意,您执行 Lablda method 的重载。

好的,我会尽量说清楚:

Expression.Lambda<Func<Arg1Type,...,ArgNType,ReturnType>>
    (body,parameterExpressionForArg1,...,parameterExpressionForArgN);

那些通用参数ArgType 必须与parameterExpressionsForArg 匹配。参数的泛型类型必须与参数的参数表达式数量相同。并且它们的类型也必须匹配。

因此,如果您出于某种原因想要树 parameterExpressions,那么您的方法中必须有树参数:

 Expression.Lambda<Func<CDNXL_TwrKarty,CDNXL_TwrKarty,CDNXL_TwrKarty, bool>>(body, parametrsNumber, parametrsTyp, parametrsLp); 

在这种情况下可能是正确的调用,显然它不会匹配 Where 调用。

如果您想将树表达式合并到一个匹配的Where 参数中,那么您必须替换所有多余的ParamteterExpressions

【讨论】:

  • 我删除了 TEntity 并为一类 pastebin.com/92PetJLK 写作。结果一样。
  • 但是,如何减少到一个参数?
  • 你需要遍历那些表达式树并创建你自己的。研究this question,我和铱星讨论了这个主题。此任务的复杂性取决于传递给您的函数的表达式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-17
  • 1970-01-01
相关资源
最近更新 更多