2010-12-07 7 views
1

NHibernateの異種コレクションでOfType <>()。Count()を実行するにはどうすればよいですか?

public class Album 
{ 
    public virtual string Name { get; set; } 
    public virtual IEnumerable<Media> { get; set; } 

    public virtual IEnumerable<Picture> 
    { 
     get { return Media.OfType<Picture>(); } 
    } 

    public virtual IEnumerable<Video> 
    { 
     get { return Media.OfType<Video>(); } 
    } 

    public virtual IEnumerable<Audio> 
    { 
     get { return Media.OfType<Audio>(); } 
    } 
} 

ここで、Mediaは抽象基本クラスであり、PictureVideo、およびAudioMediaのサブタイプであるため、IEnumerable<Media>コレクションは異種です。

Album私はこのような AlbumのDTOを持っています:

public class AlbumDTO 
{ 
    public string Name { get; set; } 
    public int PictureCount { get; set; } 
    public int VideoCount { get; set; } 
    public int AudioCount { get; set; } 
} 

各カウントは<collection>.Count();を行うことで入力されます。このコードはうまく動作し、各メディアタイプの数がわかりますが、生成されるSQLは理想よりも理想的です。

SELECT * FROM Media WHERE media.Album_id = 1 
SELECT * FROM Media WHERE media.Album_id = 2 
SELECT * FROM Media where media.Album_id = 3 

言い換えれば、まずMediaをデータベースから取得してからOfType<T>.Count()を実行します。メモリ内にある。問題は、私がすべてのAlbumsでこれを実行している場合、データベースからMediaをすべて選択することになり、数千ものレコードになる可能性があります。可能であれば、私はこのようなものを見たいと思っています(私はテーブルごとのマッピングを使用しています):

SELECT COUNT(*) FROM Media WHERE media.Album_id = 1 AND discriminator = 'Picture' 
SELECT COUNT(*) FROM Media WHERE media.Album_id = 1 AND discriminator = 'Video' 
SELECT COUNT(*) FROM Media WHERE media.Album_id = 1 AND discriminator = 'Note' 

誰でもこれを行うためにNHibernateをどのように設定できるか知っていますか?または、正しい動作を得るためにAlbumエンティティを変更する必要がありますか?

+0

あなたの設定を公開してください。 Fluent Nhibernateを使用していますか? – Aliostad

+0

私は自動化でFluent NHibernateを使用しています。それはちょうどデフォルトの規則を使用しています。 –

答えて

2

まず、コードはコンパイルされません。あなたはIEnumerable<Media>(私はそれがメディアと仮定します)のプロパティ名、およびフィルタも見当たりません。

次に、何が起こっているのか少し理解する必要があります。この動作から、HasMany関係を持つアルバムをMediaにマッピングしていることは間違いありません。 NHはデフォルトでは負荷が軽いので、DBからアルバムを最初に取得するとき、MediaにはPersistentBagというNHibernateオブジェクトへの参照が与えられます。これは、単にIEnumerableのように見えるプレースホルダであり、実際に必要なときに実際のリストを作成するロジックを保持します。 GetEnumerator()メソッドが呼び出されたとき(そしてそれは事実上すべてのLinqメソッドで発生します)、HBMでマッピングされたレコードをプルするだけです。したがって、あなたがOfTypeを呼び出すと、あなたはNHibernate IQueryableをもう使用していません。あなたが望むものを正確に実行するSQL文を構築できます。代わりに、あなたはあなたがすでに持っていると思うリストの各要素を要求しており、NHibernateはこれを遵守しています。

必要なものがすべてカウントである場合は、いくつかのオプションがあります。これは、直接DBに行くとレコードの数を取得するステートメントを構築します

session.Linq<Album>().Where(a=>a.Id = 1).Select(a=>a.Media.OfType<Picture>()).Count(); 

:最も簡単には、可能な場合は、バックセッションに戻り、アルバムの全体の新しいクエリをお願いするだけです。あなたは何かを怠惰に読み込んでいるわけではありません。リポジトリに、SQLに直接変換する方法を知っているカウントを求めています。

関連する問題