2012-03-21 24 views
2

これらのプロパティは、派生クラスでオーバーライドされています。同じ入力タイプの選択式を組み合わせる

protected virtual Expression<Func<TEntity, long>> GetIDExpr { get; } 
protected virtual Expression<Func<TEntity, string>> GetNameExpr { get; } 
protected virtual Expression<Func<TEntity, long>> GetValueExpr { get; } 

は今、私はこのクラスを持っている

public class MyData 
{ 
    public long ID { get; set; } 
    public string Name { get; set; } 
    public long Value { get; set; } 
} 

さて、基底クラスで、どのように私が呼び出されたときに、各フィールドを移入し、私はそのメソッドを作成できるようになります、Expression<Func<TEntity, MyData>>になるだろうと言いますIEnumerable<MyData>を返しますか?

Invokeの使用を避けたいのですが、これらの3つのフィールドをデータベースから選択するだけです。

注:この例では、毎回新しいインスタンスを作成するのではなく、呼び出されるたびに同じ式の式を返すように各プロパティを扱います。

編集:

public IEnumerable<MyData> GetAllData(IQueryable<TEntity> table) { 
    ParameterExpression parameter = Expression.Parameter(typeof(TEntity), "obj"); 

    List<MemberBinding> bindings = new List<MemberBinding> { 
     Expression.Bind(typeof(MyData).GetProperty("ID"), GetIDExpr.Body), 
     Expression.Bind(typeof(MyData).GetProperty("Name"), GetNameExpr.Body), 
     Expression.Bind(typeof(MyData).GetProperty("Value"), GetValueExpr.Body), 
    }; 

    var selector = Expression.MemberInit(Expression.New(typeof(MyData).GetConstructor(Type.EmptyTypes)), bindings); 

    var getBar = Expression.Lambda<Func<TEntity, MyData>>(selector, parameter); 

    return table.Select(getBar); 
} 

ここでは、クエリが実行されたとき、私は

言って、ArgumentExceptionが出ます:ここで

が動作していない私の試みであったが、パラメータ 'obj'は、指定されたLINQ to Entitiesクエリ式にバインドされていませんでした。

.Bodyを使用すると、パラメータがなくなるため、値の式が機能しないことになります。私は.Bodyを使用しない場合は、私が

引数型が

答えて

0

と一致していない私は他からの式ツリーを組み立てるための方法を知らない.Bind法上の例外を取得します式の木をラムダ式で表現するので、プログラムでツリーを構築する必要があります。このMSDNの記事(How to: Use Expression Trees to Build Dynamic Queries)は、式ツリーを使用して式ツリーを構築する方法を示しています。

この場合、newの式の後に3つのプロパティの割り当てが必要です。私はあなたが表現木でそれを行うことはできないと思います。プロパティを割り当てるコンストラクタを作成することで、それを回避することができます。

+0

コンストラクタ!私はそれを与える、歓声。 – Connell

+0

LINQ to Entitiesでは、パラメータのないコンストラクタのみがサポートされています。私はそれが起こることを知っていた。私はExpression.Assignステートメントを組み合わせることができますか? – Connell

関連する問題