ここで説明するResultTransformerの概念を使用して、次のソリューションを思いつきました。
public class DataTableResultTransformer : IResultTransformer
{
private DataTable dataTable;
public IList TransformList(IList collection)
{
var rows = collection.Cast<DataRow>().ToList();
rows.ForEach(dataRow => dataTable.Rows.Add(dataRow));
return new List<DataTable> { dataTable };
}
public object TransformTuple(object[] tuple, string[] aliases)
{
//Create the table schema based on aliases if its not already done
CreateDataTable(aliases);
//Create and Fill DataRow
return FillDataRow(tuple, aliases);
}
private DataRow FillDataRow(object[] tuple, string[] aliases)
{
DataRow dataRow = dataTable.NewRow();
aliases.ToList().ForEach(alias =>
{
dataRow[alias] = tuple[Array.FindIndex(aliases, colName => colName == alias)];
});
return dataRow;
}
private void CreateDataTable(IEnumerable<string> aliases)
{
if (dataTable == null)
{
dataTable = new DataTable();
aliases.ToList().ForEach(alias => dataTable.Columns.Add(alias));
}
}
}
そしてそれを次のように使用します:
using (ISession session = sessionFactory.OpenSession())
{
var sqlQuery = session.CreateSQLQuery("SELECT ID, NAME, ADDRESS FROM CUSTOMER");
var transformedQuery = sqlQuery.SetResultTransformer(new DataTableResultTransformer());
return transformedQuery.List().Single();
}
カスタムResultTransformerを作成し、それをSQLクエリで使用して、DataTableResultTransformerのロジックに基づいてクエリの結果を変換しました。
TransformTuppleメソッドは、結果セットのアイテムごとに呼び出されます。タプルにはデータが含まれますが、エイリアスにはデータの名前が含まれます。つまり、DataTableを構築して埋めるためのほとんどすべてが揃っています。結果セットのすべての項目がTransformTuppleメソッドによって変換されると、最後にTransformListメソッドが呼び出されます。コレクションパラメータには、TransformTuppleメソッドでDataRowに変換したすべてのアイテムが含まれています。したがって、ここでは、DataTableにDataRowsを簡単に入力して、を返すことができます。
同じ種類のシナリオを扱っている他の人に役立つことを願っています。