【发布时间】:2019-12-22 19:10:36
【问题描述】:
我想从一些 lambda 动态生成一个选择器表达式。
我想声明一个像这样的 lambda 表达式列表
Expression<Func<MyEntity, object>> select1 = myentity => myentity.Label;
Expression<Func<MyEntity, object>> select2 = myentity => myentity.User.Name;
Expression<Func<MyEntity, object>> select3 = myentity => myentity.Fields.Where(1 == 1).Select(f => f.Code).FirstOrDefault();
假设我有一堂课:
class MyClass
{
public string Label { get; set; }
public string UserName { get; set; }
public string CodeField { get; set; }
}
我想使用声明的表达式动态组合选择器表达式。 目标是我想选择要恢复的数据,而不是全部。
Expression.Lambda<Func<MyEntity, MyClass>> selectExpression = ??
req.Select(selectExpression).ToList();
我想生成一个选择器表达式来拥有这样的东西
return req.Select(myentity => new MyClass {
Label = myentity.Label,
UserName = myentity.User.Name,
CodeField = myentity.Fields.Where(1 == 1).Select(f => f.Code).FirstOrDefault()
}).ToList();
我可以这样做吗?
例如,我成功了,但这不是我想要的方式
var entityT = Expression.Parameter(typeof(MyEntity), "entity");
var propertyA = Expression.Property(entityT, typeof(MyEntity).GetProperty("Label"));
var propertyB = Expression.Property(entityT, typeof(MyEntity).GetProperty("User"));
var propertyC = Expression.Property(propertyB, typeof(UserEntity).GetProperty("Name"));
var binding = Expression.MemberInit(Expression.New(typeof(MyClass)),
new[]
{
Expression.Bind(typeof(MyClass).GetProperty("Label"), propertyA),
Expression.Bind(typeof(MyClass).GetProperty("UserName"), propertyC),
});
var selectExpression = Expression.Lambda<Func<Benef, MyClass>>(binding, entityT);
return req.Select(selectExpression).ToList();
出于同样的想法,我很想这样做,它编译但不起作用:
var binding = Expression.MemberInit(Expression.New(typeof(T)),
new[]
{
Expression.Bind(typeof(T).GetProperty("Label"), select1.Body),
Expression.Bind(typeof(T).GetProperty("UserName"), select2.Body),
});
我有这个错误: “从范围''引用'MyEntity'类型的变量'myentity',但未定义”
感谢您的回答。
【问题讨论】:
-
如何将
T.UserName映射到myentity.User.Name?你怎么知道T有UserName属性?这很可能是 XY 问题。 -
我改进了我的例子。我将 T 替换为“MyClass”
-
为什么不使用动态 linq? weblogs.asp.net/scottgu/…
标签: c# .net select lambda ef-core-2.2