24

Table Per Hierarchy 継承を使用したエンティティ モデルへの LINQ があります。基本型に対するクエリがあり、特定の型依存のロジックを実行したいと考えています。例えば:

IQueryable<BaseType> base = ...

// this works fine
var result = base.Select(b => b is DerivedType1 ? 1 : 2).ToList();

// this doesn't compile to SQL
var result2 = base.Select(b => b is DerivedType1 ? ((DerivedType1)b).DerivedProperty : null).ToList();

各派生型の IQueryables を個別に処理せずに、このようなことを行う方法はありますか?

// I'd rather not do this:
var resultA = base.OfType<DerivedType1>().Select(d => d.DerivedProperty);
var resultB = base.OfType<DerivedType2>().Select(d => default(int?));
var result = resultA.Concat(resultB).ToList();
4

5 に答える 5

31

次のようなエンティティ型への直接キャスト(DerivedType1)bは LINQ-to-Entities ではサポートされていませんが、as演算子 ( b as DerivedType1) はサポートされているため、次を試すことができます。

var result2 = base
    .Select(b => b is DerivedType1
        ? (b as DerivedType1).DerivedProperty
        : null)
    .ToList();
于 2013-04-18T16:49:47.947 に答える
1
OfType<DerivedType1>() 

は IEnumerable を返します。可能であれば、基本型を IQueryable ではなく IEnumerable に変更してみてください。IQueryable を使用すると、いくつかの SQL 制限が発生する可能性があります。

もちろん、実際にデータベースをクエリしていない場合はどうなりますか?

于 2013-04-18T13:49:24.220 に答える
1

DB への 2 回の往復を行う代わりに、EntityFramework.Extended を使用してクエリのパフォーマンスを向上させることができます。

var resultA = base.OfType<DerivedType1>().Select(d => d.DerivedProperty).Future();
var resultB = base.OfType<DerivedType2>().Select(d => default(int?)).Future();
var result = resultA.Concat(resultB).ToList();

この場合、bd への往復は 1 回だけ実行されます。このフレームワークは、他の多くの int EF に非常に役立ちます

于 2013-07-23T19:15:42.467 に答える
0

これを試してください、私はこの種のこれを行う必要があることについて何もしたことがありませんが、これはそれを行う必要があります. また、 を使用する場合base、それはキーワードであるため、まず使用しないでください。ただし、必要に応じて@base、名前の前に @ を使用すると、キーワードとして使用されていないことを示します。

var resultA = base.Select(aVar =>
                            (aVar is DerivedType1) ?
                                (DerivedType)(((DerivedType1)aVar).DerivedProperty)
                                :
                                (DerivedType)(default(int?))
                        ).ToList();
于 2013-01-09T01:16:07.857 に答える
0

関連するプロパティ値を提供するために、派生型でオーバーライドされる基本型のメソッドを持つことができます。

public class MyBaseClass
{
    public virtual int GetSomething()
    {
        throw new NotImplementedException();
    }
}

public class MyDerivedClass1 : MyBaseClass
{
    public int SomeProperty { get; set; }

    public override int GetSomething()
    {
        return this.SomeProperty;
    }
}

public class MyDerivedClass2 : MyBaseClass
{
    public int SomeOtherProperty { get; set; }

    public override int GetSomething()
    {
        return this.SomeOtherProperty;
    }
}

次に、次のことができます。

var result = base.Select(b => b.GetSomething()).ToList();
于 2012-08-31T11:55:32.983 に答える