我正在使用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)
{
// ????
}
}
我该怎么做?
答案 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);
}