C# 如何在使用查询语法的linq to entities查询中使用此扩展方法?

C# 如何在使用查询语法的linq to entities查询中使用此扩展方法?,c#,linq,linq-to-entities,linq-query-syntax,C#,Linq,Linq To Entities,Linq Query Syntax,我正在创建一个查询以从数据库返回一些数据。 我正在传递要筛选的ID列表。如果筛选器列表为null或空,我希望返回所有内容 我有一个扩展方法,可以这样做 query是一个IQueryable,Ids是一个可为null的int列表(不要问!)listhaseelements是一个方法,如果列表为非null且包含某些内容,则返回true var filteredList = query.WhereIf(ListHasElements(Ids), s => Ids.Contains(s.Id.V

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

我有一个扩展方法,可以这样做
query
是一个
IQueryable
Ids
是一个可为null的int列表(不要问!)
listhaseelements
是一个方法,如果列表为非null且包含某些内容,则返回true

 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}
var query=来自dbContext.as中的
在a.Id上的dbContext.bs中加入b。ToString()等于b.Id
将b.Id等于c.Id的cin dbContext.cs连接到bcJoin中
来自bcJoin.DefaultIfEmpty()中的项
其中b.Sent>=fromDate
其中b.发送报价来源:

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

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

引用自:

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


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

您不能。编译器获取众所周知的查询语法关键字,并在幕后将其转换为方法语法。它对您的自定义扩展一无所知,因此在查询语法中没有等价物。请注意,其他“内置”linq函数没有等效的查询语法:

  • 跳过
  • 计数
  • Take
  • Single
  • FirstOrDefault
  • Max
  • 等等
虽然我注意到你的扩展基本上等同于

where !condition || predicate(b)

你不能。编译器获取众所周知的查询语法关键字,并在幕后将其转换为方法语法。它对您的自定义扩展一无所知,因此在查询语法中没有等价物。请注意,其他“内置”linq函数没有等效的查询语法:

  • 跳过
  • 计数
  • Take
  • Single
  • FirstOrDefault
  • Max
  • 等等
虽然我注意到你的扩展基本上等同于

where !condition || predicate(b)
对!

var query=从dbContext.as.WhereIf(ListHasElements(Id),s=>Ids.Contains(s.Id.Value))中的
在a.Id上的dbContext.bs中加入b。ToString()等于b.Id
将b.Id等于c.Id的cin dbContext.cs连接到bcJoin中
来自bcJoin.DefaultIfEmpty()中的项
其中b.Sent>=fromDate
其中b.发送列表包含(s.Id))
选择l;
query.Dump();
}
公共布尔列表元素(IEnumerable it)
{
返回它。Any();
}
公共静态类Ext{
公共静态IQueryable WhereIf(此IQueryable源,布尔条件,
表达式(谓词)
{
返回条件?来源。其中(谓词):来源;
}
}

var query=从dbContext.as.WhereIf(ListHasElements(Id),s=>Ids.Contains(s.Id.Value))中的
在a.Id上的dbContext.bs中加入b。ToString()等于b.Id
将b.Id等于c.Id的cin dbContext.cs连接到bcJoin中
来自bcJoin.DefaultIfEmpty()中的项
其中b.Sent>=fromDate
其中b.发送列表包含(s.Id))
选择l;
query.Dump();
}
公共布尔列表元素(IEnumerable it)
{
返回它。Any();
}
公共静态类Ext{
公共静态IQueryable WhereIf(此IQueryable源,布尔条件,
表达式(谓词)
{
返回条件?来源。其中(谓词):来源;
}
}


方法
,其中
具有类型为
bool
的参数
条件
。你是如何传递
Ids
这是一个列表的?我把我的真实代码简化了一点:)一秒钟!您发现了一个原因,我更喜欢扩展方法语法而不是查询语法。您到底想筛选什么
dbContext.as
dbContext.bs
?为什么人们如此喜欢查询语法?我发现它更难理解。方法
WhereIf
有一个类型为
bool
的参数
condition
。你是如何传递
Ids
这是一个列表的?我把我的真实代码简化了一点:)一秒钟!您发现了一个原因,我更喜欢扩展方法语法而不是查询语法。您到底想筛选什么
dbContext.as
dbContext.bs
?为什么人们如此喜欢查询语法?我觉得很难理解我的答案很好,并在他的查询中使用他的.WhereIf。@RobertMcKee,但不是像问题所问的那样。@RobertMcKee如果
谓词
依赖于联接的结果而不仅仅是原始集合,你会怎么做?它回答了他问的问题
我可以在查询语法查询中直接使用此方法吗?
,这是肯定的。我在他的查询语法查询中使用了这个方法,它给出了他想要的结果。对我来说似乎很直截了当。@DStanley这不是问题。我的答案很好,并在他的查询中使用他的.WhereIf。@RobertMcKee,但不是像问题所问的那样。@RobertMcKee如果
谓词
依赖于联接的结果而不仅仅是原始集合,你会怎么做?它回答了他问的问题
我可以在查询语法查询中直接使用此方法吗?
,这是肯定的。我在他的查询语法查询中使用了这个方法,它给出了他想要的结果。对我来说似乎很直截了当。@DStanley这不是问题。过滤发生在最后,而不是开始。在查询语法中也没有这样做,而是使用方法语法。(您只是在避免创建第二个变量。)我在他的查询语法中使用了该方法。显然他没有
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}
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;
    }
}