在包含多个include的linq查询中使用.where()子句

本文关键字:where 子句 查询 包含多 include linq | 更新日期: 2023-09-27 18:11:20

我想获得客户的集合,包括几个属性,其中是地址,但只有当它还没有被删除(SuppressionDate == null)

IQueryable<Customer> customers =
    context.Persons.OfType<Customer>()
        .Include(customer => customer.Addresses)
        .Include(customer => customer.Bills)
        .Include(customer => customer.Code)
        .Include(customer => customer.Tutors);

我已经尝试了几种方法来使用where子句来过滤地址:

...
.Include(customer => customer.Addresses.Where(a => a.SuppressionDate == null))
.Include(customer => customer.Bills)
...

这是我的第一次尝试,但它引发了以下异常:

系统。Include路径表达式必须引用a在类型上定义的Navigation属性。使用点点路径引用导航属性和集合的选择操作符导航属性。参数名称:path

我也尝试过在Include()的末尾和查询的末尾使用相同的where子句,但似乎都不起作用。

我目前正在使用一种解决方案,即遍历客户集合并删除已删除的地址:

foreach(Customer c in customers){
    customer.Addresses = customer.Addresses.Where(a => a.SuppressionDate == null).ToList();
}

对对象/实体的linq相当陌生,我想知道是否有一个内置的方法来实现这一点。

在包含多个include的linq查询中使用.where()子句

如果你只有一个客户,你可以使用这样的显式加载:

var customer = context.Persons
    .OfType<Customer>()
    .Include(customer => customer.Bills)
    .Include(customer => customer.Code)
    .Include(customer => customer.Tutors)
    .FirstOrDefault(); //or whatever
context.Entry(customer).Collections(x => x.Addresses).Query().Where(x => x.SuppressionDate == null).Load();

生成了一个很好的查询和对数据库的两个简单调用。但在这种情况下,您将获得客户列表(或集合或其他),并且没有捷径。你的"变通方法"可能会引起数据库的大量干扰。

所以你可能只需要一步一步来:

//1. query db to get customers
var customers = context.Persons
    .OfType<Customer>()
    .Include(customer => customer.Bills)
    .Include(customer => customer.Code)
    .Include(customer => customer.Tutors)
    .ToList();
//2. make an array of all customerIds (no db interation here)
var customerIds = customers.Select(x => x.CustomerId).ToArray();
//3. query db to get addresses for customers above
var addresses = context.Addresses.Where(x => customerIds.Contains(x.CustomerId).ToList();
//4. assign addresses to customers (again, no db chatter)
foreach (var customer in customers) 
{
    customer.Addresses = addresses
        .Where(x => x.CustomerId == customer.CustomerId && x.SuppressionDate == null)
        .ToList();
}

还不错-仍然只有两个数据库查询