How to instantiate and initialize a dynamic object in expression tree?

.net, c#, dynamic, expression-trees, iqueryable

Solution

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;

You can do that, because you can write that code as as a single expression like this:

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

And you can create an expression tree that contains this expression (which EF should be able to handle) like this:

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);

Problem

When working with `IQuerayble<TItem>` we can call `Select` like this: ``` query.Select( item => new { A=item.Prop1, B=item.Prop2}); ``` And `Select` method expects `Expression<Func<TItem,TResult>>` I need to use `ExpandoObject` instead of anonymous but statically typed class. If it were possible it would look like: ``` query.Select( item => dynamic new ExpandoBoject { A=item.Prop1, B=item.Prop2}); ``` So I want to construct expression tree `Expression<Func<TItem,ExpandoObject>>` where object's properties are initialized in the similar way as with anonymous type. Dynamic functionality is only needed for initialization so it's ok that Func returns `ExpandoObject` instead of `dynamic`. I cannot find much documentation about `Expression.Dynamic` and corresponding binders I should use. Update 1 Why do I need all this stuff? Because I want to get primary keys. I want to do it for any entity type. I know how to get the list of the properties composing PK, but now I need to make a tricky projection of the entity to `EntityKey`. Well, may be to same equvalent of this class. ``` var keys = context.Set<TEntity>().Where(Expression<Func<TEntity,bool>).Select(Expression<Func<TEntity,EntityKey>>); ``` As I noted in the comments lambdas containing blocks cannot be converted to expression trees so i cannot simple create the dictionary and fill it. 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 ``` But I doubt EF can parse the expression containing blocks. Need to check. And I'm curious whether it will work with dynamic objects and Expression.MemberInit as it works with static objects. Update 2 Entity Framework does not support dictionary initialization syntax. It throws `NotSupportedException` with the message: Only list initializer items with a single element are supported in LINQ to Entities. Update 3 EF does not support block expressions aswell. `NotSupportedException` with message: Unknown LINQ expression of type 'Block'.

Original source

Related problems