3

私は式ツリーにやや慣れていないので、いくつかのことをよく理解していません。

私がする必要があるのは、値のリストを送信し、それらの値からエンティティの列を選択することです。したがって、次のような呼び出しを行います。

DATASTORE<Contact> dst = new DATASTORE<Contact>();//DATASTORE is implemented below.
List<string> lColumns = new List<string>() { "ID", "NAME" };//List of columns
dst.SelectColumns(lColumns);//Selection Command

これを次のようなコードに変換したい (Contactは EF4 を使用するエンティティです):

Contact.Select(i => new Contact { ID = i.ID, NAME = i.NAME });

だから、私は次のコードを持っているとしましょう:

public Class<t> DATASTORE where t : EntityObject
{
    public Expression<Func<t, t>> SelectColumns(List<string> columns)
    {
        ParameterExpression i = Expression.Parameter(typeof(t), "i");
        List<MemberBinding> bindings = new List<MemberBinding>();

        foreach (PropertyInfo propinfo in typeof(t).GetProperties(BindingFlags.Public | BindingFlags.Instance))
        {
            if (columns.Contains(propinfo.Name))
            {
                MemberBinding binding = Expression.Bind(propinfo, Expression.Property(i, propinfo.Name));
                bindings.Add(binding);
            }
        }

        Expression expMemberInit = Expression.MemberInit(Expression.New(typeof(t)), bindings);
        return Expression.Lambda<Func<t, t>>(expMemberInit, i);
    }

上記のコードを実行すると、次のエラーが発生しました。

エンティティまたは複合型 'Contact' は、LINQ to Entities クエリでは作成できません。

クエリの本文を確認したところ、次のコードが出力されました。

{i => new Contact() {ID = i.ID, NAME = i.NAME}}

これができるかどうかを確認するためのテストとしてこの行を明示的に書いたので、新しいエンティティを構築できるはずだと確信しています。

.Select(i => new Contact{ ID = i.ID, NAME = i.NAME })

これは機能しましたが、選択を動的に構築する必要があります。

単純なクエリを逆コンパイルしようとしましたが (低レベルのコードを初めて見たとき)、完全に翻訳できません。私が入力した高レベルのコードは次のとおりです。

Expression<Func<Contact, Contact>> expression = z => 
                    new Contact { ID = z.ID, NAME = z.NAME };

逆コンパイラで使用されるフレームワークを変更すると、次のコードが得られます。

ParameterExpression expression2;
Expression<Func<Contact, Contact>> expression = 
   Expression.Lambda<Func<Contact, Contact>>
      (Expression.MemberInit(Expression.New((ConstructorInfo) methodof(Contact..ctor),
         new Expression[0]), new MemberBinding[] { Expression.Bind((MethodInfo) 
            methodof(Contact.set_ID), Expression.Property(expression2 = Expression.Parameter(typeof(Contact), "z"), (MethodInfo) 
            methodof(Contact.get_ID))), Expression.Bind((MethodInfo) 
            methodof(Contact.set_NAME), Expression.Property(expression2, (MethodInfo) 
               methodof(Contact.get_NAME))) }), new ParameterExpression[] { expression2 
        });

これを理解するためにいくつかの場所を見てきましたが、まだ完全には理解できていません。誰でも助けることができますか?

これらは私が見たいくつかの場所です:

4

1 に答える 1

1

前回行ったとき、マップされていないクラス (エンティティではない) に結果を投影し、それが機能しました。他のすべてはコードと同じでした。.Select(i => new Contact{ ID = i.ID, NAME = i.NAME }) のような動的クエリが機能しないことは確かですか?

于 2013-03-21T14:02:00.273 に答える