Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linq 如何手动构造lambda表达式?_Linq_Lambda_Linq To Entities_Expression - Fatal编程技术网

Linq 如何手动构造lambda表达式?

Linq 如何手动构造lambda表达式?,linq,lambda,linq-to-entities,expression,Linq,Lambda,Linq To Entities,Expression,我正在使用ASP.NETWebAPI和EntityFramework5以及LINQtoEntities设计一个应用程序。WebAPI不直接提供实体,它将它们转换为一组与我的实体相似但不完全相同的数据传输对象。该API最初将由Silverlight应用程序使用,但今后我必须支持非.NET客户端(例如iOS应用程序)。我还想让客户端能够针对API运行一组健壮的查询 这些要求使我考虑了查询对象模式。本质上,我希望在客户端创建一个自制的查询对象,将其发布到Web API,并将查询对象转换为lambda表

我正在使用ASP.NETWebAPI和EntityFramework5以及LINQtoEntities设计一个应用程序。WebAPI不直接提供实体,它将它们转换为一组与我的实体相似但不完全相同的数据传输对象。该API最初将由Silverlight应用程序使用,但今后我必须支持非.NET客户端(例如iOS应用程序)。我还想让客户端能够针对API运行一组健壮的查询

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

从一个简单的比较查询开始,我希望能够在运行时将如下所示的对象转换为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)
    {
        // ????
    }
}
公共枚举查询运算符
{
无=0,
比,
比奥雷奎尔托更伟大,
埃奎尔托,
NotEqualTo,
LessThanOrEqualTo,
莱斯坦
}
公共类单纯形
{
公共单纯形()
{
this.Field=null;
this.Operator=QueryOperator.None;
this.Value=null;
}
公共字符串字段{get;set;}
公共查询运算符{get;set;}
公共对象值{get;set;}
公共IEnumerable执行(IQueryable查询目标)
{
// ????
}
}

我怎样才能做到这一点呢?

过去我不得不做这样的事情。以下是我的想法:

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);
}
public IEnumerable执行(IQueryable查询目标)
{
返回queryTarget.Where(this.getWhere表达式());
}
私有表达式GetWhereExpression()
{
var param=表达式参数(类型(T),“x”);
var prop=Expression.Property(param,this.Field);
var value=表达式.常量(this.value,prop.Type);
表达式compare=null;
开关(本操作员)
{
case QueryOperator.EqualTo:
比较=表达式。相等(属性、值);
打破
...
}
返回表达式.Lambda(比较,参数);
}

Web API支持对您公开为IQueryable的类型的本机查询功能。任何客户端(包括iOs)都可以通过URI使用WCF数据服务设置的通用查询语法进行过滤/投影/分页等。为什么要在这里重新发明轮子?这是真的,但(据我所知)它只支持通过$filter参数进行的非常简单的查询。我需要比这更强大的查询功能,比如根据相关实体的值返回实体,即加入。据我所知,WebAPI不支持这一点。