web-dev-qa-db-ja.com

誰かがnHibernateの「プロジェクション」が何であるかをよりよく説明できますか?

NHibernateとそのユーティリティライブラリであるfluentnhibernateの新しいユーザーとして、私は優れたデータベースで危険を冒すのに十分なことを学ぼうとしています。

Projectionsの概念を理解するのに非常に苦労しています。具体的には、彼らは世界で何ですか?

私は文字通り 'プロジェクションとは何ですか?'と 'nHibernateのプロジェクト'と 'nHibernate、Projections、Definition 'など。そして私はまだ非常に混乱しています。これまでで最も役立つ投稿は この他のStackOverflowの質問Colin Ramsayによるこのブログ投稿 です。しかし、私はまだ非常に混乱しています。私のデータベースに関する知識は、せいぜいエントリーレベルのままです。

予測とは何か、なぜそれらを使用したいのか、何を達成しているのかなどはよくわかりません。ブログ投稿で、彼が整数のリストを取得するためにそれらを使用していることがわかります(主キーと思われます)。それらを別のクエリで使用できますが、これは機能の仕方とその理由があいまいです。

30
Derek

これが実際の例です。

オンラインストアがあり、ドメインクラスの1つが「Samsung」のようなBrandであるとします。このクラスには、整数IdentityName、フリーテキストDescriptionフィールド、Vendorオブジェクトへの参照など、多数のプロパティが関連付けられています。

ここで、オンラインストアで提供されているすべてのブランドのリストを含むメニューを表示するとします。 session.CreateCriteria<Brand>().List()を実行するだけで、実際にすべてのブランドを取得できます。ただし、長いDescriptionフィールドとVendorsへの参照をすべてデータベースから吸い取っているので、メニューを表示するためにそれは必要ありません。必要なのはNameIdentityだけです。パフォーマンス面では、この余分なデータをすべてデータベースから吸い上げると、処理速度が低下し、不要になります。

代わりに、Identityとそれを呼び出すNameだけを含む「projection」オブジェクトを作成できます。たとえば、NameIdentityPair

public class NameIdentityPair
{
    public int Identity { get; set; }
    public string Name { get; set; }
}

また、NHibernateに、結果セットをプロジェクションに変換するように指示することで、手元のタスクを実行するために本当に必要なデータのみを選択するように指示できます。

var brandProjections = this.session.CreateCriteria<Brand>()
    .SetProjection(Projections.ProjectionList()
        .Add(Projections.Property("Name"), "Name")
        .Add(Projections.Property("Identity"), "Identity"))
    .SetResultTransformer(Transformers.AliasToBean<NameIdentityPair>())
    .List<NameIdentityPair>();

foreach (var brandProjection in brandProjections)
{
    Console.WriteLine(
        "Identity: {0}, Name: {1}", 
        brandProjection.Identity, 
        brandProjection.Name);
}

これで、Brandsのリストはなく、代わりにNameIdentityPairsのリストがあり、NHibernateはこのプロジェクションを取得するためにSELECT b.Identity, b.Name from dbo.Brand bのようなSQLステートメントのみを発行します。 Brandオブジェクト(例:SELECT b.Identity, b.Name, b.Description from dbo.brand b left join dbo.vendor v ....)。

お役に立てれば。

73

SQLに精通している場合、プロジェクションはクエリのSELECT句であり、使用可能な結果から返すフィールドを選択するために使用されます。

たとえば、PersonFirstNameLastName、およびAddressフィールドを持つPhoneがあるとします。クエリですべてを返すようにする場合は、SQLのSELECT * FROM Personのようにプロジェクションを省略できます。姓名だけが必要な場合は、FirstNameLastNameを使用してプロジェクションを作成します。これはSQL用語ではSELECT FirstName, LastName FROM Personになります。

2
Gabe

射影を使用して、SUM、COUNT ...などのSQL関数を呼び出したり、エンティティを返さずに単一のフィールドを選択したりできます。

「...エンティティ自体をトランザクションスコープにロードするオーバーヘッドなしに、1つまたは複数のエンティティのプロパティのみを取得します。これはレポートクエリと呼ばれることもあり、より正確にはプロジェクションと呼ばれます。」 [NHibernateの動作]

1
danyolgiax