我一直在研究如何动态查询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中编写此内容的任何建议。如果您可以将类型转换为属性类型,则可以使用标准运算符(==,>,<等等)进行演绎。
答案 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
。