繁体   English   中英

包含 EF Core 6 中的设置或条件

[英]Set or condition in Include EF Core 6

我需要按相关实体列表过滤产品。 例如,我有一个与名为 InventoryPrice 的产品表相关的表,其中包含颜色表的价格,我想按颜色列表过滤表产品

我使用 PredicateBuilder 来定义 Or in Loop:

 var PredicateI = PredicateBuilder.New<InventoryPriceModel>();
            
    foreach (var Color in Filter.Color)
    PredicateI = PredicateI.Or(i => i.colorId == Color);
    
    Query = Query
    .Include(i => i.InventoryPrice.Where(PredicateI))
    .ThenInclude(i => i.color);

并有这个例外:

“'System.Func 2[ClickStore.UseCases.InventoryPrice.Models.InventoryPriceModel,System.Boolean]' cannot be used for parameter of type 'System.Linq.Expressions.Expression 1[System.Func 2[ClickStore.UseCases.InventoryPrice.Models.InventoryPriceModel,System.Boolean]]' of method 'System.Linq.IQueryable ] 类型的参数2[ClickStore.UseCases.InventoryPrice.Models.InventoryPriceModel,System.Boolean]]' of method 'System.Linq.IQueryable 1[ClickStore.UseCases.InventoryPrice.Models.InventoryPriceModel] Where[InventoryPriceModel](System.Linq.IQueryable 1[ClickStore.UseCases.InventoryPrice.Models.InventoryPriceModel], System.Linq.Expressions.Expression 1[System.Func`2[ClickStore.UseCases.InventoryPrice.Models.InventoryPriceModel,System.Boolean]])' (参数 'arg1')"

我在 Where 中使用了 List.Contains:

 Query = Query
         .Include(i => i.InventoryPrice 
         .Where(i => Filter.Color.Contains(x => x == i.colorId)))
         .ThenInclude(i => i.color);

并有这个例外:

{"The LINQ expression 'x => x == EntityShaperExpression: \r\n    ClickStore.UseCases.InventoryPrice.Models.InventoryPriceModel\r\n    ValueBufferExpression: \r\n        ProjectionBindingExpression: EmptyProjectionMember\r\n    IsNullable: False\r\n.colorId' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information."}

我做了一些搜索来修复它,但仍然没有答案

更新:我提到了解决方案用户,其中三个工作没有异常,但突然也没有结果。 这是整个代码:

注意:

=> 我将默认的 UseQuerySplittingBehavior 更改为 SplitQuery。

=> 代码是部分部分的,因为它们来自不同的部分,它们要求能够在不同的请求中重用代码。

=> 我现在在没有 AsNoTracking() 和 SplitQuery() 的情况下进行了测试,没有运气

在控制器中:

var Products = _ProductRepository.SetProductsView(await _ProductRepository.GetProductsClientView(Filter).Take(Take).Skip(Skip).ToListAsync());

在 GetProductsClientView 中:

var Query = _db.Product
                .AsNoTracking()
                .Where(p => !p.productHide &&
                             p.InventoryPrice.Count > 0)
                .Include(a => a.Category)
                .Include(a => a.BrandCompany)
                    .ThenInclude(a => a.brandCompany)
                    .Include(a => a.Status)
                    .Include(a => a.Warranty)
                    .Include(a => a.ProducTag)
                    .AsQueryable();

过滤列表过滤器包括:

Query = Query
                        .Include(i => i.InventoryPrice
                        .AsQueryable().Where(i => Colors.Any(c => c.Equals(i.colorId))))
                        .ThenInclude(i => i.color);

Get and Calc, Recipts and Remittances 以检测有多少产品可用:

return Query
              .Select(ProductModel => new ProductInventoryModel
              {
                  Product = ProductModel,

                  Recipt = _db.ProductRecipt.AsNoTracking()
                  .Where(rec => rec.productId == ProductModel.productId && !rec.productReciptDisabled)
                  .Select(rec => rec.productNumber).ToList(),

                  Remittance = _db.RemittanceProduct.AsNoTracking()
                  .Where(RemP => RemP.productId == ProductModel.productId && RemP.Remittance.Status.title == "Successful" && RemP.Remittance.Order.Status.productHasTaken)
                  .Include(RemP => RemP.Remittance)
                  .ThenInclude(Rem => Rem.Status)
                  .Include(RemP => RemP.Remittance)
                  .ThenInclude(Rem => Rem.Order)
                  .ThenInclude(Rem => Rem.Status)
                  .Select(RemP => RemP.requestNumber).ToList()

              });

如果产品是 Smart Mobile:

if (CategoryId == 0)
                    Query = Query.Where(PI => PI.Product.productCategoryId == _db.ProductCategory
                  .Where(C => C.productCategoryTitle == "MobilePhone")
                  .Select(C => C.productCategoryId)
                  .FirstOrDefault());
                else
                    Query = Query.Where(PI => PI.Product.productCategoryId == CategoryId);


                return Query
                  .Join(
                    _db.MobilePhone
                    .AsNoTracking()
                    .Include(M => M.displayTechnology)
                    .Include(M => M.memoryCard)
                    .Include(M => M.network)
                    .ThenInclude(M => M.network)
                    .Include(M => M.technology)
                    .ThenInclude(M => M.technology)
                    .Include(M => M.mobilePhoneOS)
                    .Include(M => M.screenSizeRange)

                    , PI => PI.Product.productId
                    , M => M.productId
                    , (PI, M) => new ProductInventoryModel
                    {

                        Product = PI.Product,
                        Recipt = PI.Recipt,
                        Remittance = PI.Remittance,
                        Properties = M

                    });

我知道代码很长而且在第一次理解时令人困惑,也许我可以稍后或不让它变得更好,但代码正在处理结果而不插入新的过滤器代码......

你可以用纯 LINQ 做这样的事情,

List<YourColorEntity> colorList = ..... //Your color list

var yourQuery = Query
                     .Include(/*your related entities*/)
                     .Where(i => colorlist
                           .Any(c => c.colorId.Equals(i.colorId)));

而且,在您的List.Contains查询中,您缺少Include之后的右括号。

您应该可以通过在i.InventoryPrice上使用AsQueryable来解决此问题:

Query = Query
    .Include(i => i.InventoryPrice.AsQueryable().Where(PredicateI))
    .ThenInclude(i => i.color);

但是对于这种特殊情况(基于提供的代码和一些假设,因为没有提供足够的代码来测试它)简单的Contains应该可以解决问题:

Query = Query
    .Include(i => i.InventoryPrice.Where(ip => Filter.Color.Contains(ip.colorId)))
    .ThenInclude(i => i.color);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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