C# 实体框架-Linq到实体-可选过滤器

C# 实体框架-Linq到实体-可选过滤器,c#,entity-framework,linq-to-entities,entity-framework-6,C#,Entity Framework,Linq To Entities,Entity Framework 6,我正在努力弄清楚如何让LINQ语句在SQL中以单个语句生成特定的WHERE子句 我在追求这样的东西: SELECT ColA, ColB, ColC, ColN... FROM Orders WHERE Client = @ClientId AND (@CompanyId IS NULL OR @CompanyId = CompanyId) var includeAllCompanies = company == null; var data = context.Orders.Where(o

我正在努力弄清楚如何让LINQ语句在SQL中以单个语句生成特定的
WHERE
子句

我在追求这样的东西:

SELECT ColA, ColB, ColC, ColN...
FROM Orders
WHERE Client = @ClientId
AND (@CompanyId IS NULL OR @CompanyId = CompanyId)
var includeAllCompanies = company == null;
var data = context.Orders.Where(o => o.Client.Id == clientId
           && (includeAllCompanies 
                 || (c.Company != null && c.Company.Id == company.Id)).ToList();
我的(失败)LINQ语句如下所示:

SELECT ColA, ColB, ColC, ColN...
FROM Orders
WHERE Client = @ClientId
AND (@CompanyId IS NULL OR @CompanyId = CompanyId)
var includeAllCompanies = company == null;
var data = context.Orders.Where(o => o.Client.Id == clientId
           && (includeAllCompanies 
                 || (c.Company != null && c.Company.Id == company.Id)).ToList();
但是,当变量
company
为NULL时,它总是抛出异常(初始化后它工作正常。例外情况是:

我当前的解决方案是将LINQ语句一分为二。一个使用
表达式(要转换为带有部分筛选的SQL语句)。然后是另一个使用
Func
对返回的列表执行其余过滤器的函数

Expression
让SQL做一些工作(不包括可为空的对象)

Func
然后过滤掉可为空的对象

var data = context.Orders.Where(o => o.Client.Id == clientId).ToList();
data = data.Where(c => (territory == null 
       || (c.Territory != null && c.Territory.Id == territory.Id))).ToList();

这是可行的,但是,我希望SQL执行此查询。

问题是,
公司
是服务器端变量。关于
includealcompanies
value,EF必须将整个LINQ查询转换为SQL—在这种情况下,SQL不知道什么是
company.Id
—因此EF必须始终获取
company.Id
值才能放入SQL查询。即使
company
为空(这就是为什么会出现异常)。我希望你明白我的意思,如果不明白的话,我会尽量提供一些样品

为了消除异常,您可以执行以下操作:

var companyId = company == null ? null  : (int?)company.Id;
var data = context.Orders.Where(o => o.Client.Id == clientId
           && (companyId  == null
                 || (c.Company != null && c.Company.Id == companyId)).ToList();