你如何手动构建一个lambda表达式?

时间:2013-04-02 15:45:35

标签: linq lambda linq-to-entities expression

我正在使用ASP.NET Web API和Entity Framework 5以及LINQ to Entities设计应用程序。 Web API不直接提供实体,它将它们转换为一组与我的实体相似但不相同的数据传输对象。该API最初将由Silverlight应用程序使用,但我将不得不支持非.NET客户端(例如iOS应用程序)。我还想让客户端能够针对API运行一组强大的查询。

这些要求让我考虑了查询对象模式。本质上,我想创建一个本地查询对象客户端,将其发布到Web API,并将查询对象转换为我可以在LINQ to Entities中使用的lambda表达式。最后一部分是让我失望的。

从简单的比较查询开始,我希望能够在运行时将类似于以下内容的对象转换为lambda表达式。

public enum QueryOperator
{
    None = 0,
    GreaterThan,
    GreaterThanOrEqualTo,
    EqualTo,
    NotEqualTo,
    LessThanOrEqualTo,
    LessThan
}

public class SimpleQuery<T>
{
    public SimpleQuery()
    {
        this.Field = null;
        this.Operator = QueryOperator.None;
        this.Value = null;
    }

    public string Field { get; set; }
    public QueryOperator Operator { get; set; }
    public object Value { get; set; }

    public IEnumerable<T> Execute(IQueryable<T> queryTarget)
    {
        // ????
    }
}

我该怎么做?

1 个答案:

答案 0 :(得分:1)

过去我必须做这样的事情。这就是我想出的:

public IEnumerable<T> Execute(IQueryable<T> queryTarget)
{
    return queryTarget.Where(this.GetWhereExpression<T>());
}

private Expression<Func<T, bool>> GetWhereExpression<T>()
{
    var param = Expression.Parameter(typeof(T), "x");
    var prop = Expression.Property(param, this.Field);
    var value = Expression.Constant(this.Value, prop.Type);
    Expression compare = null;
    switch(this.Operator) 
    {
        case QueryOperator.EqualTo:
            compare = Expression.Equal(prop, value);
            break;
        ...
    }

    return Expression.Lambda(compare, param);
}