web-dev-qa-db-ja.com

基準APIを使用してNHibernateから異なる結果セットを取得しますか?

NHibernateのCriteria APIを使用して明確な結果を取得しようとしています。これはHQLを使用して可能であることはわかっていますが、アプリの残りの部分はこのメソッドのみを使用して記述されているため、Criteria APIを使用してこれを実行したいと思います。私 このフォーラムの投稿を見つけました ですが、機能させることができません。異なる結果セットを取得する基準APIを使用する方法はありますか?

編集:これを行う際に、IDでもある主キー列を除外し、残りの個別のレコードを取得したいと考えました。これを行う方法はありますか?このように、主キーは行ごとに一意ですが、他のすべてのフィールドは同じであるため、個別のレコードは重複を返します。

29
Mark Struzinski

現時点ではフォーラムの投稿(リンク切れ?)が表示されないので、おそらくこれは答えではありませんが、DistinctRootEntityResultTransformerを追加できます。

session.CreateCriteria(typeof(Product)
    .Add(...)
    .SetResultTransformer(new DistinctEntityRootTransformer())
25
Juanma

個別のクエリを実行するには、条件の射影をProjections.Distinctに設定します。次に、返す列を含めます。次に、結果トランスフォーマーをAliasToBeanResultTransformerに設定することにより、結果を厳密に型指定されたオブジェクトに戻します-結果の変換先の型を渡します。この例では、エンティティ自体と同じタイプを使用していますが、このクエリ専用に別のクラスを作成することもできます。

ICriteria criteria = session.CreateCriteria(typeof(Person));
criteria.SetProjection(
    Projections.Distinct(Projections.ProjectionList()
        .Add(Projections.Alias(Projections.Property("FirstName"), "FirstName"))
        .Add(Projections.Alias(Projections.Property("LastName"), "LastName"))));

criteria.SetResultTransformer(
    new NHibernate.Transform.AliasToBeanResultTransformer(typeof(Person)));

IList<Person> people = criteria.List<Person>();

これにより、(少なくともSQL Serverでは)次のようなSQLが作成されます。

SELECT DISTINCT FirstName, LastName from Person

プロジェクションで指定したプロパティのみが結果に入力されることに注意してください。

このメソッドの利点は、すべての結果をアプリケーションに返してからフィルタリングを実行するのではなく、データベースでフィルタリングが実行されることです。これはDistinctRootEntityTransformerの動作です。

89
Aidan Boyle

価値があるのは、 NHibernate:プロジェクションを使用したクエリの最適化 は、基本的にこの同じ問題を解決するのに役立ちました。

6
Jon Adams