我正在创建一个查询以从数据库返回一些数据。 我传递了一个我要过滤的ID列表。如果过滤器列表为null或为空,我想返回所有内容。
我有一个扩展方法可以让我这样做
query
是IQueryable
,Ids
是可以为空的整数列表(不要问!)ListHasElements
是一种方法,如果列表为非,则返回true null并且有一些东西。
var filteredList = query.WhereIf(ListHasElements(Ids), s => Ids.Contains(s.Id.Value));
但是当我构建query
时,我使用了我首选的查询语法
var query = from a in dbContext.as
join b in dbContext.bs on a.Id.ToString() equals b.Id
join cin dbContext.cs on b.Id equals c.Id into bcJoin
from items in bcJoin.DefaultIfEmpty()
where b.Sent >= fromDate
where b.Sent <= toDate
select new{a=a.thing, b=b.thingy, q=items.q,Id=a.Id}
然后我必须插入初始行来做我的魔法WhereIf过滤器。最后进一步选择分组并创建我的输出对象(代码未显示!)
扩展方法如下所示。
public static IQueryable<TSource> WhereIf<TSource>(this IQueryable<TSource> source, bool condition,
Expression<Func<TSource, bool>> predicate)
{
return condition ? source.Where(predicate) : source;
}
我可以直接在查询语法查询中使用此方法吗?
答案 0 :(得分:1)
答案 1 :(得分:0)
你不能。编译器采用众所周知的查询语法关键字并将它们转换为幕后方法语法。它对您的自定义扩展名一无所知,因此在查询语法中没有等效内容。请注意其他内置&#34; linq函数没有等效的查询语法:
Skip
Count
Take
Single
FirstOrDefault
Max
虽然我会注意到你的扩展基本上等同于
where !condition || predicate(b)
答案 2 :(得分:-1)
YES!
var query = from a in dbContext.as.WhereIf(ListHasElements(Ids), s => Ids.Contains(s.Id.Value))
join b in dbContext.bs on a.Id.ToString() equals b.Id
join cin dbContext.cs on b.Id equals c.Id into bcJoin
from items in bcJoin.DefaultIfEmpty()
where b.Sent >= fromDate
where b.Sent <= toDate
select new{a=a.thing, b=b.thingy, q=items.q,Id=a.Id}
我的测试代码(清单是带有Id字段的表):
void Main()
{
var list=new int []{1,2,3,4};
var query=from l in Listings.WhereIf(ListHasElements(list),s=>list.Contains(s.Id))
select l;
query.Dump();
}
public bool ListHasElements<T>(IEnumerable<T> it)
{
return it.Any();
}
public static class Ext {
public static IQueryable<TSource> WhereIf<TSource>(this IQueryable<TSource> source, bool condition,
Expression<Func<TSource, bool>> predicate)
{
return condition ? source.Where(predicate) : source;
}
}