简体   繁体   中英

Entity Framework - Linq to Entities - Optional filter

I am struggling to figure out how to get a LINQ statement to produce a specific WHERE clause in SQL in a single statement.

I am after it producing something like this:

SELECT ColA, ColB, ColC, ColN...
FROM Orders
WHERE Client = @ClientId
AND (@CompanyId IS NULL OR @CompanyId = CompanyId)

My ( failing ) LINQ statement looks like this:

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

However, it always throws an exception when the variable company is NULL ( it works fine when it has been initialised ). The exception being:

 Non-static method requires a target. 

My current fix is to split my LINQ statement into two. One using an Expression<Func<>> (to be transformed to a SQL statement with partial filtering). Then another that uses Func<> to perform the remaining filters on the returned list.

Expression<Func<>> to let SQL do some of the work (excluding nullable objects)

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

Func<> to then filter out the nullable objects

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

This works, however, I want SQL to be performing this query.

The problem is that, company is server-side variable. Regardles includeAllCompanies value, EF has to translate whole LINQ query to SQL - and in this case SQL doesn't know what is company.Id - so EF has to always get company.Id value in order to put into SQL query. Even if company is null (so that is why you get exception). I hope you see my point, if not - I'll try to give some sample.

In order get rid of exception you can do the following:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM