如何使用查询语法在linq to entity查询中使用此扩展方法?

时间:2015-11-03 17:08:11

标签: c# linq linq-to-entities linq-query-syntax

我正在创建一个查询以从数据库返回一些数据。 我传递了一个我要过滤的ID列表。如果过滤器列表为null或为空,我想返回所有内容。

我有一个扩展方法可以让我这样做 queryIQueryableIds是可以为空的整数列表(不要问!)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;
}

我可以直接在查询语法查询中使用此方法吗?

3 个答案:

答案 0 :(得分:1)

引自MSDN

  

某些查询必须表示为方法调用

这是其中一个案例。甚至一些自己的扩展方法也必须通过方法语法调用。例如,Count

答案 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;
    }
}