【发布时间】:2021-04-22 04:17:21
【问题描述】:
我目前正在与这样的勇士一起购买产品
products = context.Products
.Include(x => x.Skus)
.Include(x => x.ProductVariants)
.ThenInclude(pv => pv.Option)
.Include(x => x.ProductVariants)
.ThenInclude(pv => pv.Value);
现在我正在尝试通过OptionId 和ValueId 添加过滤功能
以下列表包含在 UI 中选择的每个选项的 OptionId 和 ValueId
List<Filter> filters;
过滤器在哪里
public class Filter
{
public int Oid { get; set; } //OptionId
public int Vid { get; set; } //ValueId
}
如何在这个上添加过滤功能?
使用后
var v = context.Products.Include(x => x.ProductVariants)
.Where(prod => prod.ProductVariants
.Any(v => filters.Any(f => f.Oid == v.OptionId && f.Vid == v.ValueId)));
我收到了错误
The LINQ expression 'DbSet<ProductVariant>()
.Where(p0 => EF.Property<Nullable<int>>(EntityShaperExpression:
EntityType: Product
ValueBufferExpression:
ProjectionBindingExpression: EmptyProjectionMember
IsNullable: False
, "Id") != null && object.Equals(
objA: (object)EF.Property<Nullable<int>>(EntityShaperExpression:
EntityType: Product
ValueBufferExpression:
ProjectionBindingExpression: EmptyProjectionMember
IsNullable: False
, "Id"),
objB: (object)EF.Property<Nullable<int>>(p0, "ProductId")))
.Any(p0 => __filters_0
.Any(f => f.o == p0.OptionId && f.v == p0.ValueId))' 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.
更新 使用时
var vv = context.ProductVariants
.Where(v => filters.Any(f => f.Oid == v.OptionId && f.Vid == v.ValueId)).AsEnumerable();
现在是错误
The LINQ expression 'DbSet<ProductVariant>()
.Where(p => __filters_0
.Any(f => f.Oid == p.OptionId && f.Vid == p.ValueId))' could not be translated.
更新 即使仅按选项过滤,错误仍然存在
var vv = context.ProductVariants
.Where(v => filters.Any(f => f.Oid == v.OptionId)).AsEnumerable();
更新使用的类是
public class Product
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public IEnumerable<ProductVariant> ProductVariants { get; set; }
public IEnumerable<Sku> Skus { get; set; }
}
public enum FilterType
{
CheckBox,
Radio,
Button,
List
}
public class Option
{
public int OptionId { get; set; }
public string OptionName { get; set; }
public FilterType FilterType { get; set; }
}
public class Value
{
public int ValueId { get; set; }
public string OptionValue { get; set; }
}
public class Sku
{
public int SkuId { get; set; }
public int ProductId { get; set; }
public decimal Price { get; set; }
[ForeignKey("ProductId")]
public Product Product { get; set; }
}
public class ProductVariant
{
public int Id { get; set; }
public int ProductId { get; set; }
public int OptionId { get; set; }
public int ValueId { get; set; }
public int SkuId { get; set; }
[ForeignKey("ProductId")]
public Product Product { get; set; }
[ForeignKey("OptionId")]
public Option Option { get; set; }
[ForeignKey("ValueId")]
public Value Value { get; set; }
[ForeignKey("SkuId")]
public Sku Sku { get; set; }
}
更新
我已经缩小了与Filter 类相关的错误
通过使用
List<int> ints = new List<int>();
ints.Add(1);
和
var vv = context.ProductVariants
.Where(v => ints.Any(f => f == v.OptionId));
它只是工作。我应该使用表达式还是别的什么?
static Expression<Func<...
【问题讨论】:
-
你尝试了什么?您的包含确实无关紧要。此外,像这样缩写名称也是不好的做法,特别是考虑到它们需要的解释性 cmets。代码应尽可能自我记录
-
不使用的时候为什么要包含Sku?
-
为什么您的过滤器类有
Oid和Vid但您声称崩溃的查询有f.o和f.v? -
@我已在本地将 FilterClass 中的 Oid 重命名为 o 和 Vid 重命名为 v。很抱歉产生任何混淆。我刚刚更新了原始实体
-
@CaiusJard sku 应该是返回到 MVC 视图的模型的一部分
标签: c# linq entity-framework-core .net-5