Linq to Entities的动态

时间:2014-10-10 17:00:11

标签: c# linq dynamic linq-to-entities dynamic-linq

我一直在研究如何动态查询linq。我正在为Web应用程序创建UI,允许他们从数据库中选择属性并设置where子句动态构建报表。我在堆栈或其他网站上看到的所有问题都使用Dynamic Linq和LinqKit来解决问题,例如Here。但是,我无法找到表达语法的解决方案。

// This attempts to grab out a title whose from the Database whose
// Copyright Date equals 2006
propName = "CopyrightDate";
Model.Titles.Where(t => t.GetType().GetProperty(propName).GetValue(t, null) == "2006");

我想做这样的事情但是在Linq to Entities中。 Linq to entities并不支持这样的反射,我不想提取所有数据并运行Linq to Object,DB太大了。有关如何在Dynamic Linq中编写此内容的任何建议。如果您可以将类型转换为属性类型,则可以使用标准运算符(==,>,<等等)进行演绎。

2 个答案:

答案 0 :(得分:2)

LINQ-to-entities Where扩展方法需要的是Expression<Func<T, bool>>。您可以创建如下表达式:

// Create lambda expression: t => t.CopyrightDate == "2006"
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
var lambda = Expression.Lambda<Func<T, bool>>(
     Expression.Equal(
         Expression.Property(parameter, "CopyrightDate"),
         Expression.Constant("2006")
     ),
     parameter
);

其中T是包含CopyrightDate属性的类的类型。

var result = context.Titles
    .Where(lambda)
    .ToList();

更通用的解决方案是:

Expression<Func<T, bool>> Comparison<T>(ExpressionType comparisonType,
                                        string propertyName, object compareTo)
{
    ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
    MemberExpression property = Expression.Property(parameter, propertyName);
    ConstantExpression constant = Expression.Constant(compareTo);
    Expression body = Expression.MakeBinary(comparisonType, property, constant);
    return Expression.Lambda<Func<T, bool>>(body, parameter);
}

答案 1 :(得分:0)

以下是使用Dynamic Linq重写查询的方法:

var propName = "CopyrightDate";
var propValue = "2006";
Model.Titles.Where(string.Format("{0}=@0", propName), propValue);

string.Format("{0}=@0", propName)生成Where子句的查询字符串,在这种情况下为"CopyrightDate=@0"@0指定查询的参数,该参数变为propValue