1

ネイティブSQLで複雑な検索クエリを作成します。基本的には次のようなものです。

SELECT ID FROM t_Product WHERE Name LIKE @criteria
SELECT publisher, count(*) as number FROM t_Product GROUP BY publisher

2つSELECTのステートメントがあり、1回のラウンドトリップでDBサーバーに送信したいと思います。

しかし、Nhibernateでこれを実現する方法がわかりません。

次のオプションを検討しましたが、どれも機能しないようです

  1. を使用CreateMultiQueryしますが、これはHQLのみを受け入れ、ネイティブSQLは受け入れません
  2. を使用しますが、List()を呼び出すと、最初のステートメントCreateSQLQueryの結果のみが返されますSELECT
  3. SQL全体が非常に動的であるため、ストアドプロシージャに移動することはできません。
  4. まだNhibernate1.2を使用しているため、それ以降のバージョンの新機能も使用できませんでした。

アドバイスは大歓迎です。

4

4 に答える 4

1

これは実際にはシナリオ固有のものになりますが、NH バージョン 1.2 に行き詰まっていて、ラウンドトリップを排除することが目標である場合は、サブ選択を使用してこれを単一のクエリとして書き直すことを検討できます。

次のようなもの:

SELECT publisher, count(*) as number, 
(SELECT ID FROM t_Product WHERE Name LIKE @criteria) As theId 
FROM t_Product GROUP BY publisher

サブクエリが単一の値のみを返す場合に機能します。

于 2012-04-16T17:31:05.083 に答える
1

NH バージョン 1.2 を使用することはできません

Futures はバージョン 2.1 でリリースされ、まさにこれを行うことができます。

例えば

var blogs = s.CreateCriteria<Invoice>()
  .SetMaxResults(30)
  .Future<Invoice>();
var countOfInvoices = s.CreateCriteria<Invoice>()
  .SetProjection(Projections.Count(Projections.Id()))
  .FutureValue<int>();

したがって、アップグレードするか、ADO.NET にフォールバックして複数のレコードセットを使用するか、既存のものをそのまま使用するかのいずれかになります。ごめん!

于 2012-04-16T06:04:58.443 に答える
0

次のように MultiQuery "Hack" を使用できます。

手順:

CREATE PROCEDURE [dbo].[proc_Name]
AS BEGIN
    SELECT * FROM t_Question where ...
    SELECT * FROM t_Question where ........
END

NHibernate クエリ コード:

public void ProcdureMultiTableQuery()
{
    var session = Session;
    var procSQLQuery = session.CreateSQLQuery("exec [proc_Name] ?,?");// prcodure returns two table
    procSQLQuery.SetParameter(0, userId);
    procSQLQuery.SetParameter(1, page);
    procSQLQuery.AddEntity(typeof(Question));

    var multiResults = session.CreateMultiQuery()
        .Add(procSQLQuery)
        // More table your procedure returns,more empty SQL query you should add
        .Add(session.CreateSQLQuery(" ").AddEntity(typeof(Question))) // the second table returns Question Model
        .List();
    if (multiResults == null || multiResults.Count == 0)
    {
        return;
    }
    if (multiResults.Count != 2)
    {
        return;
    }
    var questions1 = ConvertObjectsToArray<Question>((System.Collections.IList)multiResults[0]);
    var questions2 = ConvertObjectsToArray<Question>((System.Collections.IList)multiResults[1]);
}

static T[] ConvertObjectsToArray<T>(System.Collections.IList objects)
{
    if (objects == null || objects.Count == 0)
    {
        return null;
    }
    var array = new T[objects.Count];
    for (int i = 0; i < array.Length; i++)
    {
        array[i] = (T)objects[i];
    }
    return array;
}
于 2015-11-29T13:51:40.497 に答える
0

両方のクエリが SELECT であるため、可能だとは思いません。

最初のクエリの後にセミコロンを入力し、その間に 2 つの改行を入れることができます。これは、一部のデータベースでは必要です。このようなクエリスクリプトを正常に実行しました。実行された場合は、デバッガを使用して何が返されるかを確認してください...

これがうまくいかない場合は、別の往復が必要になるか、HQL / Criteria に切り替える必要があります。

于 2012-04-16T06:24:41.410 に答える