实体框架 - Linq to Entities - 可选过滤器

时间:2015-10-09 08:46:30

标签: 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)

我的(失败的)LINQ语句如下所示:

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时,它总是抛出一个异常(初始化后它可以正常工作)。唯一的例外是:

Non-static method requires a target.

我目前的解决方法是将LINQ语句拆分为两个。一个使用Expression<Func<>>(要转换为带有部分过滤的SQL语句)。然后是另一个使用Func<>在返回列表上执行剩余过滤器的人。

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

var data = context.Orders.Where(o => o.Client.Id == clientId).ToList();

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

data = data.Where(c => (territory == null 
       || (c.Territory != null && c.Territory.Id == territory.Id))).ToList();

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

1 个答案:

答案 0 :(得分:2)

问题是,company是服务器端变量。 Regardles includeAllCompanies值,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();