2016-06-22 18 views
3

一般的な列に基づいて2 tablesを結合する汎用のextensionメソッドを作成しました。 、今databaseのテーブルが2つの共通の列(ID、タイプ)を持って、私は2つの共通の列に基づいてこれらのテーブルを結合するための一般的な拡張メソッドを記述する必要が2列を使用したLINQ JOINの汎用拡張メソッド

public class SomeDTO<T,U> 
    { 
     public T TableA { get; set; } 
     public U TableB { get; set; } 
    } 
    public static class Helper 
    { 
     public static IQueryable<SomeDTO<T,U>> JoinExtension<T,U,Key>(this IQueryable<T> tableA, IQueryable<U> tableB, Expression<Func<T,Key>> columnA, Expression<Func<U,Key>> columnB) 
     { 
      return tableA.Join(tableB, columnA, columnB,(x, y) => new SomeDTO<T, U>{TableA = x,TableB = y}); 
     } 
    } 

何かを書いた:コードは以下の通りです。以下のように:それは理解することができません

The type arguments for method 'Queryable.Join<TOuter, TInner, TKey, TResult>(IQueryable<TOuter>, IEnumerable<TInner>, Expression<Func<TOuter, TKey>>, Expression<Func<TInner, TKey>>, Expression<Func<TOuter, TInner, TResult>>)' cannot be inferred from the usage. Try specifying the type arguments explicitly. 

public static IQueryable<SomeDTO<T, U>> JoinExtensionTwoColumns<T, U, Key>(this IQueryable<T> tableA, IQueryable<U> tableB, Expression<Func<T, Key>> columnA, Expression<Func<U, Key>> columnB, Expression<Func<T, Key>> columnC, Expression<Func<U, Key>> columnD) 
    { 
    return tableA.Join(tableB, a => new { columnA, columnB }, b => new { columnC, columnD }, (a, b) => new SomeDTO<T, U> { TableA = a, TableB = b }); 
    } 

コンパイラは、以下のようなエラーが....コードtableA.Joinの行で、以下のように述べて、私を与えますargumentsとその性質が正しくあります。

私が間違っているかもしれないどこへのポインタ?

EDIT:

私は今、正常にコンパイルする方法がありますが、私のようなメソッド呼び出し "The LINQ expression node type 'Lambda' is not supported in LINQ to Entities."

public static IQueryable<SomeDTO<T, U>> JoinExtensionTwoColumns<T, U, Key>(this IQueryable<T> tableA, IQueryable<U> tableB, Expression<Func<T, Key>> columnA, Expression<Func<U, Key>> columnB, Expression<Func<T, Key>> columnC, Expression<Func<U, Key>> columnD) 
     { 
return tableA.Join(tableB, a => new object[]{ columnA, columnB }, b => new object []{ columnC, columnD }, (a, b) => new SomeDTO<T, U> { TableA = a, TableB = b }); 
} 

ことをランタイムエラーを取得:

var result= (db.table1.JoinExtensionTwoColumns<table1,table2,int>(db.table2, c => c.id.ToString(), d => d.id.ToString(),e => e.type, f => f.type)).Take(10); 

これ以上ポインタはありません。

+0

をあなたは持っています名前が必要な匿名型:new {columnA、columnB}(2つの場所)。代わりにobject:new object [] {columnA、columnB}を使用することもできます。どのタイプも自動的にオブジェクトにキャストされますが、タイプオブジェクトを特定のタイプに割り当てるときにキャストする必要があります。 – jdweng

+0

@ jdweng ..私はあなたが言ったことを試みました。コンパイラエラーは発生しませんが、ランタイムエラー 'LINQ式のノードタイプ' Lambda 'はLINQ to Entitiesでサポートされていません。'私はそれを理解しようとしています。ありがとう – Anurag

+0

@jdweng:編集を参照して、いくつかの指摘をしてください。ありがとう – Anurag

答えて

3

あなたはすでにすべての作業を行っている:

tableA.JoinExtension<TypeA, TypeB, object>(tableB, x => new { x.column1, x.column2 }, 
    x => new { column1 = x.column2, column2 = x.column3 }); 

しかし、この場合では - に起因していないTypeSafelyソリューションJoinExtensionTwoColumns方法が必要とされていない、あなたはいくつかのの列に基づいてテーブルを結合するためにJoinExtensionを使用することができます

public static class Helper 
{ 
    public class JoinCondition<TFirst, TSecond> 
    {    
     public TFirst column1 { get; set; } 
     public TSecond column2 { get; set; } 
    } 

    public static IQueryable<SomeDTO<T, U>> JoinExtension<T, U, TFirst, TSecond>(this IQueryable<T> tableA, IQueryable<U> tableB, 
     Expression<Func<T, JoinCondition<TFirst, TSecond>>> joinSelectorA, 
     Expression<Func<U, JoinCondition<TFirst, TSecond>>> joinSelectorB) 
    { 
     return tableA.Join(tableB, joinSelectorA, joinSelectorB, (x, y) => new SomeDTO<T, U> { TableA = x, TableB = y }); 
    } 
} 
: - 第三 任意 object型パラメータは、それを修正するには、以前のソリューションをこのようにリファクタリングします

Implementaion:

var answer = context.TableA.JoinExtension(context.TableB, 
    x => new Helper.JoinCondition<int, string> { column1 = x.prop1, column2 = x.prop2}, 
    x => new Helper.JoinCondition<int, string> { column1 = x.prop3, column2 = x.prop4} 
    ).ToList(); 

P.S. JoinExtensionTwoColumns方法は誤りが含まれています。あなたは、列として columnA、columnBとなどを使用していますが、彼らは述語です、あなたは それをこのように(それはEFコンテキストでは動作しません)修正することができます:

public static IQueryable<SomeDTO<T, U>> JoinExtensionTwoColumns<T, U, Key>(this IQueryable<T> tableA, IQueryable<U> tableB, 
    Expression<Func<T, Key>> columnA, Expression<Func<U, Key>> columnB, 
    Expression<Func<T, Key>> columnC, Expression<Func<U, Key>> columnD) 
{ 
    return tableA.Join(tableB, 
     a => new { column1 = columnA.Compile()(a), column2 = columnC.Compile()(a) }, 
     b => new { column1 = columnB.Compile()(b), column2 = columnD.Compile()(b) }, 
     (a, b) => new SomeDTO<T, U> { TableA = a, TableB = b }); 
} 
+0

@Slava ...答えをありがとう。あなたの提案を試してみましょう。 – Anurag

+0

@Slava ... JoinExtensionTwoColumnsを編集すると、 'LINQ式のノードタイプ' Invoke 'がLINQ to Entitiesでサポートされていませんが、ランタイムエラーが生成されます。'それに関するアイデア?一方、私はあなたの最初のアプローチを試みています。 – Anurag

+0

このエラーは、おそらくEFコンテキストでこのクエリを実行するために発生します。もちろん、それは起こりますが、あなたはこの事実をあなたが疑問視して指定しません。単純な 'List 'コレクションでこのアプローチを試してみると、すべてがうまくいくでしょう。 –

関連する問題