【问题标题】:Using .Where() clause inside an .Include() on a linq query with multiples includes在具有多个包含的 linq 查询上的 .Include() 内使用 .Where() 子句
【发布时间】:2015-09-04 08:27:16
【问题描述】:

我想获得一个客户集合,包括几个属性,其中是地址,但只有在它尚未被删除时 (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)
...

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

System.ArgumentException : 包含路径表达式必须引用 在类型上定义的导航属性。使用虚线路径 参考导航属性和用于集合的 Select 运算符 导航属性。参数名称:路径

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

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

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

对 linq to object/entities 相当陌生,我想知道是否有内置方法可以实现这一点。

【问题讨论】:

标签: c# linq-to-entities where


【解决方案1】:

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

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

还不错 - 仍然只是对数据库的两个查询。

【讨论】:

    猜你喜欢
    • 2016-02-05
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 1970-01-01
    • 2018-08-14
    • 2021-02-03
    • 1970-01-01
    • 2020-07-06
    相关资源
    最近更新 更多