[英]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.Func2[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.IQueryable1[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.