2

LINQ to SQL で条件付き射影を行うことは可能ですか? PersonTable という 1 つの SQL テーブルがあるとします。C# には、いくつかのクラスがあります。

public interface Person
{
 int employeeType; //1 is employee, 2 is manager
 String name;
}

および 2 つの派生クラス。簡単にするために:

public class Employee : Person {}
public class Manager : Person {}

次に、LINQ to SQL を使用して、employeeType に基づいて適切な派生クラスに投影します。

IQueryable<IPerson> = PersonTable.Select(x => //x.employeeType == 1 ? new Employee { } : x == 2 {new Manager {} )

これはこの状況では問題ありませんが、7 つの異なる派生型をインスタンス化しようとしている状況があるため、条件が長くなり、非常に速くなります。また、私の現実のシナリオでは、インターフェイス/派生クラスには、入力するプロパティが 15 ほどあります。これも長くなり、すぐに醜くなります。

私の最初の試みは、適切な型を返す式ツリーを作成することでしたが、Expression.MemberInit を正しく呼び出すにはパラメーター式の値を知る必要があるため、うまくいきません。LINQ to SQL を使用したこのような大規模な条件付き初期化に最適なソリューションは何ですか。

プロジェクション内でデータ転送オブジェクトを作成しているため、テーブル継承を使用できません。where と union を使用することも考えましたが、式ツリー ルートは、新しい派生クラスが導入されるたびにコードを維持する場所が 1 つあるという点で、より興味深いようです (これがオプションである場合)。

4

1 に答える 1

1

多分あなたはこれを行うことができます、

PersonTable.Where(p => p.employeeType == 1)
    .Select(p => new Employee { ... })
    .Cast<IPerson>()
    .Concat(
        PersonTable.Where(p => p.employeeType == 2)
            .Select(p => new Manager { ... })
            .Cast<IPerson>());

あなたも試すことができます、

PersonTable.Select(p => 
     p.employeeType == 1 ? (IPerson)(new Employee { ... }) :
     p.employeeType == n ? (IPerson)(new Other { ... }) :
     (IPerson)(new Manager { ... }));

または、そうである必要がない場合はIQueryable

PersonTable.AsEnumerable().Select(p => {
    switch(p.employeeType)
    {
        case 2:
            return Manager { ... };

        default:
            return Employee { ... };   
    }});
于 2013-02-05T15:31:47.423 に答える