6

コンテキスト
Web アプリケーションを作成しています。その機能の 1 つは、UI を介して DB クエリを許可することです。永続性のために、nHibernate ORM を使用します。以下は、受信した SQL クエリを処理するリポジトリ メソッドです。

public IList ExecuteSqlQuery(string sqlQuery)
{
    var query = Session.CreateSQLQuery(sqlQuery);
    var queryResult = query.SetResultTransformer(Transformers.AliasToEntityMap).List();

    return queryResult;
}  

問題
上記のメソッドは、それぞれがKey = ColumnNameおよびValue = ColumnValueを持つDictionaryEntryオブジェクトを含む辞書のリストを返します。

列名が元の SQL クエリで指定された順序と同じでないことを除けば、これで問題ありません。たとえば、次の SQL クエリです。

select FirstName, LastName, c.Name   
from SoftwareDeveloper sf  
join Certification c on  sf.SoftwareDeveloperId = c.SoftwareDeveloperId  

、次のような各行を返します。

["FirstName"] = "John"
["Name"] = "70-515  MCTS, .NET Framework 4, Web Applications"
["LastName"] = "Doe"  

列の順序は保持されないことに注意してください。そのはず:

["FirstName"] = "John"  
["LastName"] = "Doe"  
["Name"] = "70-515  MCTS, .NET Framework 4, Web Applications"  

UPDATE 上記の例では、ディクショナリのキーは名前順に並べられていますが、これはこの例にのみ適用され、意図的に単純化されています。より大きなクエリの場合、キー (= 列) は順序付けされていません。

このコンテキスト (nHibernate/CreateSQLQuery) での質問
、元のクエリで指定された列の順序を保持するにはどうすればよいですか?

UPDATE#2
ソリューション
IResultTransformer の次のカスタム実装を作成することで解決しました。

public class DictionaryResultTransformer : IResultTransformer
{
    #region IResultTransformer Members
    public IList TransformList(IList collection)
    {
        return collection;
    }

    public object TransformTuple(object[] tuple, string[] aliases)
    {
        var result = new Dictionary<string, object>();
        for (int i = 0; i < aliases.Length; i++)
        {
            result[aliases[i]] = tuple[i];
        }
        return result;
    }
    #endregion
}  

上記のコードでは、エイリアスは列名です。

ソース:
nhibernate がクエリをエンティティ クラスではなく IDictionary として返すことは可能ですか?
https://github.com/nhibernate/nhibernate-core/blob/master/src/NHibernate/Transform/AliasToEntityMapResultTransformer.cs

4

1 に答える 1

2

これらはキーの順序を定義しないため、結果を辞書として取得することはできません。そのため、AliasToEntityMap の使用を、順序を保持するデータ構造を構築するものに置き換える必要があります (IResultTransformer を実装します)。SortedDictionary は、列名から列インデックスに内部的にマップする比較子を指定すると機能する可能性があります。

結果トランスフォーマーを使用せずに List() を直接呼び出す場合は、オブジェクト配列のリストを取得する必要があることに注意してください。要素の順序は、select 句で指定された順序に従います。

于 2012-12-09T14:39:36.240 に答える