C# EF核心动态表达式生成器
我正在尝试建立一个动态EF过滤系统 查询:C# EF核心动态表达式生成器,c#,entity-framework,lambda,C#,Entity Framework,Lambda,我正在尝试建立一个动态EF过滤系统 查询: var query = _db.Promotions.Select(x => new ListPromotionAdminResponseModel() { ActionUrl = x.ActionUrl, Approved = x.Approved, ForShop = x.Shop.Name, Id = x.Id,
var query = _db.Promotions.Select(x => new ListPromotionAdminResponseModel()
{
ActionUrl = x.ActionUrl,
Approved = x.Approved,
ForShop = x.Shop.Name,
Id = x.Id,
Name = x.Name,
Categories = x.Categories.Select(y => new CategoryResponseModel() { Id = y.CategoryId, Name = y.Category.Name })
});
尝试使用过滤器来充实IQueryable
// Works as expected
query = query.Where(x => x.Name == "Name");
// Doesn't work
var parameter = Expression.Parameter(typeof(ListPromotionAdminResponseModel), "x");
MemberExpression member = Expression.Property(parameter, "Name"); ;
query = query.Where(Expression.Lambda<Func<ListPromotionAdminResponseModel
, bool>>(Expression.Equal(member, Expression.Constant("test")), parameter));
//按预期工作
query=query.Where(x=>x.Name==“Name”);
//不起作用
var parameter=Expression.parameter(typeof(ListPromotionAdminResponseModel),“x”);
MemberExpression member=Expression.Property(参数“Name”);
query=query.Where(Expression.Lambda(Expression.Equal(成员,Expression.Constant(“test”)),参数));
但是,动态表达式不计算预期值,并返回以下异常:
System.InvalidOperationException: The LINQ expression 'DbSet<Promotion>
.Join(
outer: DbSet<Shop>,
inner: p => EF.Property<Nullable<Guid>>(p, "ShopId"),
outerKeySelector: s => EF.Property<Nullable<Guid>>(s, "Id"),
innerKeySelector: (o, i) => new TransparentIdentifier<Promotion, Shop>(
Outer = o,
Inner = i
))
.Where(p => new ListPromotionAdminResponseModel{
ActionUrl = p.Outer.ActionUrl,
Approved = p.Outer.Approved,
ForShop = p.Inner.Name,
Id = p.Outer.Id,
Name = p.Outer.Name,
Categories = DbSet<CategoryPromotion>
.Where(c => EF.Property<Nullable<Guid>>(p.Outer, "Id") != null && EF.Property<Nullable<Guid>>(p.Outer, "Id") == EF.Property<Nullable<Guid>>(c, "PromotionId"))
.Join(
outer: DbSet<Category>,
inner: c => EF.Property<Nullable<int>>(c, "CategoryId"),
outerKeySelector: c0 => EF.Property<Nullable<int>>(c0, "Id"),
innerKeySelector: (o, i) => new
TransparentIdentifier<CategoryPromotion, Category>(
Outer = o,
Inner = i
))
.Select(c => new CategoryResponseModel{
Id = c.Outer.CategoryId,
Name = c.Inner.Name
}
)
}
.Name == "test")' 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 either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
System.invalidoOperationException:LINQ表达式“DbSet”
.加入(
外部:DbSet,
内部:p=>EF.Property(p,“ShopId”),
outerKeySelector:s=>EF.Property(s,“Id”),
innerKeySelector:(o,i)=>新的透明标识符(
外部=o,
内部=i
))
.Where(p=>new ListPromotionAdminResponseModel{
ActionUrl=p.Outer.ActionUrl,
批准=p.Outer.Approved,
ForShop=p.Inner.Name,
Id=p.Outer.Id,
Name=p.Outer.Name,
类别=数据库集
其中(c=>EF.Property(p.Outer,“Id”)!=null和&EF.Property(p.Outer,“Id”)==EF.Property(c,“PromotionId”))
.加入(
外部:DbSet,
内部:c=>EF.Property(c,“CategoryId”),
outerKeySelector:c0=>EF.Property(c0,“Id”),
innerKeySelector:(o,i)=>新建
透明剂(
外部=o,
内部=i
))
.Select(c=>newcategoryresponsemodel{
Id=c.Outer.CategoryId,
Name=c.Inner.Name
}
)
}
.Name==“test”)”无法翻译。以可以翻译的形式重写查询,或者通过插入对AsEnumerable()、AsAsAsAsyncEnumerable()、ToList()或ToListSync()的调用显式切换到客户端计算。看见https://go.microsoft.com/fwlink/?linkid=2101038 了解更多信息。
例外结束
这两条语句的调试lambda树是相同的。我在这里犯了什么新手错误?如果执行Where中的部分(不工作的代码)不会引发任何异常,则在评估Where中的“不工作”时会引发异常。InvalidOperationException描述中给出的树由EF和invalid生成。看来这个表达式的位置不对,所以你的问题在中间框中?为什么表达式不像
x.Name==“Name”
?在您的异常中无法找到此部分,它只是以.Name==“test”)结尾。
无法翻译。这看起来很奇怪。你构建了一个巨大的对象ListPromotionAdminResponseModel,你所做的只是测试它的名称,然后把它扔掉?它没有存储或返回到任何地方。我没有看到任何Where(x=>,其中x是一个ListPromotionAdminResponseModel。也许你的Where(p=>应该是一个Select?我已经更新了这个问题,以澄清第三个框是一个例外。我只想动态地重现'query=query.Where(x=>x.Name==“Name”)“当然,不同的值不同,但为了简单起见,我已将查询的复杂性降至最低。您不能更改操作顺序吗?过滤,强制加载,然后获取结果,而不是(现在)定义结果,过滤,然后加载。因此更改为\u db.Promotions.Where(expression).ToList()。选择(x=>new ListPromotionAdminResponseModel…
。其中ToList
是关键部分。