私はEF 6で困惑しています....私はパフォーマンスの面で非常にひどく動作するWebアプリケーションを持っています。分析中、EF6エンティティ上でコレクションが空であるかどうかをチェックする私の方法である犯人の1つが見つかりました。EF6 - 私が期待したことをしない.Any()
基本的に、私が持っている:私のアプリで
public partial class BaseEntity
{
public int BaseEntityId { get; set; }
public string Name { get; set; }
// a few more properties, of no concern here....
// a lazily loaded collection of subitems
public virtual ICollection<Subitem> Subitems { get; set; }
}
public partial class Subitem
{
public int SubitemId { get; set; }
public int BaseEntityId { get; set; }
public string Name { get; set; }
// a few more properties, of no concern here....
}
を、私はBaseEntity
の特定のインスタンスが「空」であるか否かをチェックする必要がある - 何のサブ項目を有していないと定義されています。だから私は、第二の部分クラスファイルにこの方法CheckIfEmpty
を追加しました:今
public partial class BaseEntity
{
public bool IsEmpty
{
return !Subitems.Any();
}
}
単一BaseEntity
は、サブ項目の数百または数千を持つことができます - ので、私は、任意のサブ項目があったかどうかをチェックするために最も効率的な方法を使用していました。またはそれらの線に沿って何か - - ただの項目が存在していたかどうかをチェックする - マイ仮定がデータベースからまだロードされていないコレクションで.Any()
を呼び出すと、基本的に
IF EXISTS(SELECT * FROM dbo.Subitems) ......
SQL呼び出しに変換というものでしたかない。私は具体的にはより.Count > 0
を選択しました。なぜなら、カウントのチェックでコレクション全体が列挙される必要があることがわかっていて、アイテムが存在するかどうかを知りたいときには非常に非効率的です。
私は存在し、また私は彼らの細部に興味がありますどのように多くのを知っている必要はありません- 十分であろうis empty?
質問には、単純なYESまたはNO。私の大きな驚き(およびbedazzlement)へ
、それはEF6がコレクション全体をロードSELECT
ステートメントに、この単純な.Any()
コールをオン判明します! - か - - それは間違いなく私は......
駆け引きいたものではありませんので、未ロードのコレクションは、任意の値を持っている場合、単純にをチェックする簡単な方法があるなしデータベースから完全なコレクションをロードしますか?イーガーローディングアプローチを使用してDbSetを照会することにより
:
context.Set<TEntity>().Any();
はに翻訳されこれは怠惰な読み込みが実装されている方法です。最初に 'Subitems'にアクセスすると、それがロードされます。私はレイジーローディングを使用しないことを試みますが、それは私のコードを複雑にします:私はできるだけ早くコンテキストを閉じ、 'db.Subitem.Any(si => si。BaseEntityId == .. ) ' – Kobi
' SubItems'は 'ICollection'です。 'IQueryable'であれば期待通りに動くかもしれません(I'm確かではありません。レイジーローディングが' IQueryable'でも使えるかどうかはわかりません) –
Eagerのロード方法を使用してDbSetをクエリすると、あなたが望むものを手に入れよう: context.Set()。どれか(); MSDNの(ビットとして0)ELSE CAST(BIT AS 1)CAST THEN ( が[M]と[TEntity] FROM 1 選択) END –
alessalessio