c# - 如何在表达式树中实例化和初始化动态对象?

标签 c# .net dynamic expression-trees iqueryable

使用 IQuerayble<TItem> 时我们可以调用Select像这样:

query.Select( item => new { A=item.Prop1, B=item.Prop2});

Select方法需要 Expression<Func<TItem,TResult>>

我需要使用 ExpandoObject而不是匿名但静态类型的类。

如果可能的话,它看起来像:

query.Select( item => dynamic new ExpandoBoject { A=item.Prop1, B=item.Prop2});

所以我要构造表达式树Expression<Func<TItem,ExpandoObject>>其中对象的属性以与匿名类型类似的方式初始化。
动态功能仅在初始化时需要,因此 Func 返回 ExpandoObject 是可以的而不是 dynamic .

我找不到很多关于 Expression.Dynamic 的文档以及我应该使用的相应 Binder 。


更新 1

为什么我需要这些东西?
因为我想get primary keys .
我想为任何实体类型执行此操作。

我知道如何获取构成 PK 的属性列表,但现在我需要对实体进行棘手的投影到 EntityKey .好吧,可能与此类相同。

var keys = context.Set<TEntity>().Where(Expression<Func<TEntity,bool>).Select(Expression<Func<TEntity,EntityKey>>);

正如我在评论中指出的,包含 block 的 lambda 不能转换为表达式树,所以我不能简单地创建字典并填充它。现在我正在使用语义上接近此代码的表达式树:

var dict = new Dictionary<string,object>();
dict.Add("Prop1",value1);
dict.Add("Prop2",value2);
return dict

但我怀疑 EF 能否解析包含 block 的表达式。需要检查。
我很好奇它是否适用于动态对象和 Expression.MemberInit,因为它适用于静态对象。


更新 2

Entity Framework 不支持字典初始化语法。
它抛出 NotSupportedException带有消息:在 LINQ to Entities 中仅支持具有单个元素的列表初始值设定项。


更新 3

EF 也不支持 block 表达式。
NotSupportedException带有消息:“ block ”类型的未知 LINQ 表达式。

最佳答案

Now I'm playing with the expression tree semantically close to this code:

var dict = new Dictionary<string,object>();
dict.Add("Prop1",value1);
dict.Add("Prop2",value2);
return dict;

可以这样做,因为您可以将该代码编写为像这样的单个表达式:

new Dictionary<string, object>
{
    { "Prop1", value1 },
    { "Prop2", value2 }
};

您可以像这样创建一个包含此表达式(EF 应该能够处理)的表达式树:

var addMethod = typeof(Dictionary<string, object>).GetMethod("Add");

var expression = Expression.Lambda<Func<Dictionary<string, object>>>(
    Expression.ListInit(
        Expression.New(typeof(Dictionary<string, object>)),
        Expression.ElementInit(
            addMethod,
            Expression.Constant("Prop1"),
            value1Expression),
        Expression.ElementInit(
            addMethod,
            Expression.Constant("Prop2"),
            value2Expression)),
    itemParameterExpression);

关于c# - 如何在表达式树中实例化和初始化动态对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18340622/

相关文章:

c# - 使用 winforms 和 C# 在 ResumeLayout() 上静默崩溃 Win7 64bit

c# - 以编程方式获取 SQL 集群虚拟名称

.net - 有人知道用于对SaaS用户进行计费和身份验证的服务吗?

javascript - Javascript 数组中的动态串联

javascript - 事件监听器在某些上下文中无法附加或删除

c# - winforms 中的数据转发器控件

c# - 如何在 EF6 Code First 中将泛型类型与数据库上下文一起使用

c# - 捕获异常并保持 GUI 逻辑分离

c# - 如何访问 Task.Factory.StartNew 中的 HttpContext.Current?

javascript - 在javascript中设置动态变量名