首页 > 解决方案 > EF Core 条件(添加)包含到 IQueryable

问题描述

在 EF6 中,我习惯于这样做:

var orders = GetAllEntities().Include(x => x.Contact.User);
if (includeProducts)
{
    orders = orders.Include(x => x.ProductOrders.Select(y => y.RentStockOrders));
    orders = orders.Include(x => x.ProductOrders.Select(y => y.Product));
    orders = orders.Include(x => x.ProductOrders.Select(y => y.Currency));
    orders = orders.Include(x => x.ProductOrders.Select(y => y.Coupons));
    orders = orders.Include(x => x.AdditionalCosts);
    orders = orders.Include(x => x.Partner);
    orders = orders.Include(x => x.OrderCoupons.Select(y => y.Coupon.Partner));
    if (includeStock)
    {
        orders = orders.Include(x => x.ProductOrders.Select(y => y.RentStockOrders.Select(z => z.Stock)));
    }
}
if (includeInvoices)
{
    orders = orders.Include(x => x.Invoices.Select(y => y.Attachments));
}

在 EF Core 中无法覆盖IQueryable,因为它更“类型安全”

第一行返回 a IIncludableQueryable<Order, User>,所以当我做第二个 Include 时,它​​想让它变得不同,例如IIncludableQueryable<Ordr,User,ProductOrder>

我主要有一个GetByIdWithCrudRelations包含一组布尔值来选择要包含的内容和不包含的内容。有时它只有两个,但在这种情况下它有 8 个,这意味着如果我需要 if-else 一切,它可能会有很多不同的结果。

有人对此有聪明的解决方案吗?

标签: c#entity-framework-coreiqueryable

解决方案


您可以使用完全相同的模式。只需从IQueryable<T>变量开始(注意IIncludableQueryable<T, P>仍然IQueryable<T>有额外的ThenInclude支持)并使用ThenInclude而不是嵌套Selects:

IQueryable<Order> orders = GetAllEntities().Include(x => x.Contact.User);
// or var orders = GetAllEntities().Include(x => x.Contact.User).AsQueryable();
if (includeProducts)
{
    orders = orders.Include(x => x.ProductOrders).ThenInclude(y => y.RentStockOrders);
    orders = orders.Include(x => x.ProductOrders).ThenInclude(y => y.Product);
    orders = orders.Include(x => x.ProductOrders).ThenInclude(y => y.Currency);
    orders = orders.Include(x => x.ProductOrders).ThenInclude(y => y.Coupons);
    orders = orders.Include(x => x.AdditionalCosts);
    orders = orders.Include(x => x.Partner);
    orders = orders.Include(x => x.OrderCoupons).ThenInclude(y => y.Coupon.Partner);
    if (includeStock)
    {
        orders = orders.Include(x => x.ProductOrders).ThenInclude(y => y.RentStockOrders).ThenInclude(z => z.Stock);
    }
}
if (includeInvoices)
{
    orders = orders.Include(x => x.Invoices).ThenInclude(y => y.Attachments);
}

请注意,由于ThenIncludechain 不是嵌套的,因此不需要不同的变量名x,yz- 单个x或类似的也可以。

此外,由于Include从根重新启动包含链,因此orders = orders.Include(...)可以组合非条件分配,例如

orders = orders
    .Include(x => x.ProductOrders).ThenInclude(y => y.RentStockOrders)
    .Include(x => x.ProductOrders).ThenInclude(y => y.Product)
    .Include(x => x.ProductOrders).ThenInclude(y => y.Currency)
    .Include(x => x.ProductOrders).ThenInclude(y => y.Coupons)
    .Include(x => x.AdditionalCosts)
    .Include(x => x.Partner)
    .Include(x => x.OrderCoupons).ThenInclude(y => y.Coupon.Partner);

推荐阅读