动态生成LINQ查询
本文关键字:查询 LINQ 动态 | 更新日期: 2023-09-27 18:26:06
我们有一个对象
public class SomeObject
{
public Name {get;set;}
public City {get;set;}
public State {get;set}
//various other parameters. Let's say there's ~20
}
是否可以在不重新编译源代码的情况下动态创建新的LINQ查询?相反,查询参数来自存储并更新在数据库中的XML结构。
var result = from i in someObj
where
//XML requests Name = 'Bob'...so append this where clause
name = 'Bob'
这能做到吗?
这里有一个带有表达式树的解决方案:
var param = Expression.Parameter(typeof(SomeObject), "p");
var exp = Expression.Lambda<Func<SomeObject, bool>>(
Expression.Equal(
Expression.Property(param, "Name"),
Expression.Constant("Bob")
),
param
);
var query = someObj.Where(exp);
我知道它要复杂得多,但这有时可能有用。
我很难根据你的问题来判断,但在某些情况下,你不需要动态Linq,只需这样做。。。
var result = from o in someObj
where (Name == null || o.Name == Name)
&& (City == null || o.City == City)
&& (State == null || o.State == State)
select o;
当有问题的参数为null时,这将从根本上防止数据被过滤。由于C#中的短路行为,它仍然表现良好。
您肯定想了解一下Dynamic Linq,它将允许您将查询条件定义为文本。
至于动态添加条件,可以使用与类似的语法向查询添加条件;
if(CategoryIsImportant)
myQuery = myQuery.Where("CategoryId=2");
所有这些都可以(相当容易)编码为您选择的XML格式。
我相信您必须深入研究表达式树。我还没有深入研究,所以我不能为您创建一个示例,但我知道您可以使用表达式树动态构建查询,然后调用.Compile(在代码中)使其可运行。
实际上,这里有一个更好的链接,用表达式树构建动态查询。它应该给你想要的东西,并且非常简洁。这应该是一个很好的例子:)
也许Dynamic Linq可以帮助您:Dynamic Linq第1部分:使用Linq动态查询库
query = query.Where("Id = 123 And Age > 18");
或者您可以直接操作您的Linq查询:
query = query.Where(x=>x.Id == 5);
我认为您希望引入可选的过滤器,这取决于XML的内容。继续StriplingWarrior:的例子
var name = GetNameFromXml();
var city = GetCityFromXml();
var state = GetStateFromXml();
var result = someObj;
if (name != null)
result = result.Where(i => i.Name == name);
if (city != null)
result = result.Where(i => i.City == city);
if (state != null)
result = result.Where(i => i.State == state);
通过这种方式,您将应用任意数量的过滤器(从没有到全部三个),这取决于XML中实际指定的内容。
是的,这其实很容易:
var name = GetBobNameFromXml();
var result = someObj.Where(i => i.Name == name);
您还可以选择是否逐段应用条件。
var result = someObj;
var name = xmlCriteria.Name;
if(!string.IsNullOrEmpty(name))
{
result = result.Where(i => i.Name == name);
}
// follow the same pattern for city, state, etc.
您甚至可以使用一种使用标准函数的名称键控字典的模式,以避免出现一堆if
语句。
foreach(var criterionPair in xmlCriteria)
{
var value = criterionPair.Value;
result = result.Where(i => propGetters[criterionPair.PropertyName](i, value));
}
基本上,你可以沿着这些路线做很多事情。如果你想要一个更适合你的情况的答案,你需要提供一个更具体的问题。