6

を使用して取得したすべての個別のアカウント名プレフィックス(az)のリストがあります

var accounts = this.SessionManager.GetActiveSession().QueryOver<Account>();

var q = accounts.Select(Projections.Distinct(
        Projections.SqlFunction("substring", 
                                NHibernateUtil.String, 
                                Projections.Property("Name"),
                                Projections.Constant(1),
                                Projections.Constant(1))));

ただし、個別のリストを返す代わりに、プレフィックスをグループ化し、そのプレフィックスで始まるアカウントの数を返すことをしたいのですが、クエリを使用してグループを実行する方法がわかりません。これは、標準ほど単純ではないためです。 linq。

クエリではなくクエリオーバーを使用している理由は、何らかの理由でサブストリング関数がデータベースサーバーではなくメモリで実行されているためです。

これは私が通常それをする方法です

var prefixes = (from acc in this.SessionManager.GetActiveSession().Query<Account>()
              group acc by acc.Name.Substring(0, 1)
              into grp
              select new
                       {
                         Prefix = grp.Key,
                         Count = grp.Count()
                       });

編集これは私が試したものですが、次のエラーが発生しました

式の認識されないメソッド呼び出しSqlFunction( "substring"、NHibernateUtil.String、new [] {Property( "Name")、Constant(Convert(1))、Constant(Convert(1))})

var accounts = this.SessionManager.GetActiveSession().QueryOver<Account>().Select(
            Projections.Group<string>(x => Projections.SqlFunction("substring", NHibernateUtil.String,
                                                       Projections.Property("Name"), Projections.Constant(1),
                                                       Projections.Constant(1))),
            Projections.Count<string>(x => Projections.SqlFunction("substring", NHibernateUtil.String,
                                                       Projections.Property("Name"), Projections.Constant(1),
                                                       Projections.Constant(1)))

          );
4

3 に答える 3

4

他のすべてが失敗した場合は、Projections.SqlGroupProjectionを使用してそれを行うことができます!

var accounts = _busDb.Session.QueryOver<QueueEntity>()
        .Select(
            Projections.SqlGroupProjection(
                "SUBSTRING({alias}.Name, 1) as FirstChar", 
                "SUBSTRING({alias}.Name, 1)",
                new[] {"FirstChar"},
                new[] {NHibernateUtil.String}),
            Projections.Count("id"));

最初の引数はselectで選択されたもの、2番目の引数はグループ化されたもの、3番目の引数は選択された列の名前、4番目の引数は選択されているデータのタイプです。

于 2012-06-01T12:29:53.700 に答える
3

名前の最初の文字を別の列に格納することにより、部分文字列クエリの必要性を排除することを検討しましたか?

SQL Serverを使用していると仮定すると、テーブルを挿入/更新するコードを更新する必要がないように、SQLServerを永続的な計算列にすることができます。

この列を含むインデックスを追加する機能も、クエリのパフォーマンスを向上させるのに役立ちます。

于 2012-06-01T12:42:28.997 に答える
3

あなたのリストはどれくらい大きいですか?1000未満の場合は、SQLサーバーからアイテムリストを収集し、リストに対してクエリを実行して通常のグループを実行します

var sqlout= (from acc in this.SessionManager.GetActiveSession().Query<Account>()
          select new
                   {
                     Name = acc.Name,
                     col1= acc.col1
                   }).TolList();

その後

var prefixes = (from acc in sqlout
          group acc by acc.Name.Substring(0, 1)
          into grp
          select new
                   {
                     Prefix = grp.Key,
                     Count = grp.Count()
                   });

サブストリング関数は、SQLサーバーではなくC#リストで実行されるため、ここで機能します

于 2012-05-31T17:18:01.100 に答える