5

次のケースを検討してください。

別の2つに継承された基本クラスがあります。たとえば、次のようになります。

class Base
{

}
class DerivedA : Base
{

}
class DerivedB : Base
{

}

次のようなコードでベースエンティティをリクエストすると

context.Base.Where(q => q.Id == id).First();

Entity Framework は、すべての派生エンティティへの結合の完全なセットを生成するため、クエリのパフォーマンスが許容範囲を下回ります。私が望むのは、派生エンティティに結合せずに基本エンティティのみをロードすることです。

私が見つけた唯一の解決策は、http://blogs.msdn.com/b/alexj/archive/2009/09/17/tip-35-how-to-write-oftypeonly-tentity.aspxに記載されています。しかし、それは私にはうまくいきませんでした。EF は依然として巨大なクエリを生成します。

次のようなクエリを記述します。

context.Base.Where(q => !(q is DerivedA) && !(q is DerivedB)).First();

派生型の量が絶えず増加しているため、私にも適していません。

私が言及したもの以外に考えられる解決策はありますか?

4

2 に答える 2

5

Table-per-type を使用しています => EF は、エンティティが実際にどのタイプであるかがわからないため、これらの結合を生成する必要があります。レコードのテーブルBaseに関連するレコードがある場合、そのレコードのエンティティのインスタンスを作成してはなりません-のインスタンスを作成する必要があり、この知識を得るために結合を行う必要があります。DerivedABaseDerivedA

これが許可されない理由は長い議論ですが、単にエンティティはオブジェクトの世界からのものです - 複数のテーブルに保存できるアトミックデータ構造ですが、オブジェクトの世界には見えません。a を永続化すると aBaseをロードバックしますBaseが、永続DerivedA化すると常にロードバックし、エンティティの原子性を壊すという理由DerivedAだけでロードバックすることはありません。Base

OFTYPE ONLY私はそれを試しませんでしたが、派生エンティティの破損したインスタンスではなく、基本エンティティの実際のインスタンスを実際にロードすることを確認するために、ESQL演算子も結合を行う必要があると思います。

Table-per-type ではクエリが遅くなります。OfType.NET 4.5 では改善されるはずですが、改善の対象はこれらのケースではなく、派生型とプロジェクションが対象になると思います。

テーブルからのデータのみが必要な場合Base、最良のオプションは次のとおりです。

于 2012-07-19T16:14:22.947 に答える
0

すべての派生型が派生しなければならない意味/機能を持たない抽象中間クラスを導入できます。

class Base
{

}
abstract class DerivedBase : Base
{

}
class DerivedA : DerivedBase 
{

}
class DerivedB : DerivedBase 
{

}

次に、派生クラスがいくつ存在するかを気にせずに簡単なクエリを実行できます。

context.Bases
  .Where(b => !(b is DerivedBase))
  ...
于 2015-09-29T15:08:32.593 に答える