7

基本クラスと2つの派生クラスがあります。

派生クラスのそれぞれは、プロパティと同じタイプを実装します。唯一の違いは、プロパティ名です。

残念ながら、クラスの設計にはあまり影響しません->wsdlファイルから生成されています。

次に、BaseTypeに、共通のプロパティをカプセル化するためのプロパティがあります。計画は、このプロパティを私のWebビューなどで使用することでした。

私はこの問題を実証するために有名な「果物の例」を使用しました。

 public class FruitBase
    {
        public virtual int ID { get; set; }


        //
        // The plan is to use this property in mvc view
        //
        [NotMapped]
        public virtual FruitnessFactor Fruitness
        {
            get
            {
                if (this.GetType().BaseType == typeof(Apple))
                    return ((Apple)this).AppleFruitness;
                else if (this.GetType().BaseType == typeof(Orange))
                    return ((Orange)this).OrangeFruitness;
                else
                    return null;
            }
        }
    }

public class FruitnessFactor { }

私のMVCコントローラーでは、次のクエリは完全に正常に機能します。

return View(context.FruitEntities
                           .OfType<Apple>().Include(a =>a.AppleFruitness)
                           .ToList());

しかし、これはそうではありません:

  return View(context.FruitEntities
                                   .OfType<Apple>().Include(a =>a.AppleFruitness)
                                   .OfType<Orange>().Include(o => o.OrangeFruitness)
                                   .ToList());

私が受け取るエラーメッセージは次のとおりです。

DbOfTypeExpressionには、type引数と互換性のある多態的な結果型を持つ式引数が必要です。

私はEF5.0RCとCodeFirstアプローチを使用しています。

どんな助けでも大歓迎です!

4

1 に答える 1

9

私が知る限りInclude、単一のデータベース クエリで複数のサブタイプに適用することはできません。1 つのタイプ ( OfType<Apple>().Include(a => a.AppelFruitness)) を照会し、別のサブタイプについても同じことを照会できます。問題は、結果コレクションのジェネリック型が異なるため (リンゴとオレンジ)、同じクエリで結果を連結できないことです。

1 つのオプションは、2 つのクエリを実行し、結果のコレクションを基本型の新しいコレクションにコピーすることです。これは、質問の下のコメント セクションで既に示したとおりです。

もう 1 つのオプション (クエリは 1 つしか必要ありません) は射影です。射影型を定義する必要があります (匿名型に射影することもできます)...

public class FruitViewModel
{
    public FruitBase Fruit { get; set; }
    public FruitnessFactor Factor { get; set; }
}

...そしてクエリを使用できます:

List<FruitViewModel> fruitViewModels = context.FruitEntities
    .OfType<Apple>()
    .Select(a => new FruitViewModel
    {
        Fruit = a,
        Factor = a.AppleFruitness
    })
    .Concat(context.FruitEntities
    .OfType<Orange>()
    .Select(o => new FruitViewModel
    {
        Fruit = o,
        Factor = o.OrangeFruitness
    }))
    .ToList();

変更の追跡を (を使用して) 無効にしないAsNoTracking場合、エンティティがコンテキストにアタッチされると (「リレーションシップの修正」)、ナビゲーション プロパティが自動的に設定されます。これは、viewModel コレクションから果物を抽出できることを意味します...

IEnumerable<FruitBase> fruits = fruitViewModels.Select(fv => fv.Fruit);

...そして、プロパティを含む果物を取得します。FruitnessFactor

このコードはかなり厄介ですが、プロジェクションを使用しない直接的なアプローチが何度か求められてきましたが、成功しませんでした:

于 2012-06-14T19:29:36.443 に答える