コンテキスト
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