2015-10-09 83 views
1

我正在努力弄清楚如何获得LINQ语句,以在单一语句中的SQL中生成特定的WHERE子句。实体框架 - Linq到实体 - 可选过滤器

我就生产这样的事情后:

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执行此查询。

回答

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(); 
+0

伟大的作品,谢谢! – JBond