如何在DataGridView 中显示nHibernate CreateSQLQuery 的结果?
How to show the result of nHibernate CreateSQLQuery in DataGridView?
我在 nHibernate 中得到了一个查询结果:
var result = _Session.CreateSQLQuery("SELECT 'just a string' as Type, NAME FROM SCHEMA.PERSON where NAME like ('%A%')").List();
我想在 DataGridView 中显示此结果。所以我尝试了:
this.results.DataSource = result;
但这不起作用(它只显示了很多东西,如 "Length"、"Long Length"、"Rank" 等等,但不是实际的 sql 结果) 因为结果是类型: System.Collections.IList System.Collections.Generic.List 实际上看起来像 object 数组里面的 object 数组。
所以我尝试了:
this.results.DataSource = from res in result.Cast<List<object[]>>()
select new
{
T = res[0][0],
V = res[0][1]
};
但这只显示了一个空控件。
那么如何显示结果,作为一项高级任务,如何将 alias/select 结果名称显示为列 Headers?
顺便说一句。这应该适用于每个 SQL。所以我不能使用 mappingFiles.
经过这个问题的大量搜索和帮助:NHibernate output columns/projections of CreateQuery().list()
我找到了适合我的解决方案:
var query = _Session.CreateSQLQuery("SELECT 'just a string' as Type, NAME FROM SCHEMA.PERSON where NAME like ('%A%')").SetResultTransformer(Transformers.AliasToEntityMap);
var result = query.List();
var tab = new DataTable();
if (result.Count > 0)
{
var asHash = result[0] as Hashtable;
foreach (DictionaryEntry item in asHash)
{
tab.Columns.Add(item.Key as string);
}
foreach (Hashtable item in result)
{
var newobj = new Object[tab.Columns.Count];
int i = 0;
foreach (DictionaryEntry row in item)
{
newobj[i]= row.Value;
i++;
}
tab.Rows.Add(newobj);
}
}
this.results.DataSource = tab;
我确定还有其他(更好的)方法可以做到这一点,但是嘿:它有效。
其他解决方案不保留投影顺序。我实现了这个(丑陋的)数据转换器来保持顺序:
Usage example:
var command = "SELECT 'just a string' as Type, NAME FROM SCHEMA.PERSON where NAME like ('%A%')";
var query = _Session.CreateSQLQuery(command)
.SetResultTransformer(new DataTableTransformer());
var dataTable = (DataTable)query.List()[0];
Implementation:
public class DataTableTransformer : IResultTransformer
{
bool _isHeaderRowAdded;
public object TransformTuple(object[] tuple, string[] aliases)
{
if (false == _isHeaderRowAdded)
{
_isHeaderRowAdded = true;
return new Tuple<string[], object[]>(aliases, tuple);
}
return tuple;
}
public IList TransformList(IList collection)
{
if (collection.Count == 0)
{
return new []{new DataTable()};
}
var dataTable = new DataTable();
var headerAndFirstRow = (Tuple<string[], object[]>)collection[0];
foreach (var columnName in headerAndFirstRow.Item1)
{
dataTable.Columns.Add(columnName);
}
var newRow = dataTable.NewRow();
newRow.ItemArray = headerAndFirstRow.Item2;
dataTable.Rows.Add(newRow);
int index = 0;
foreach (var item in collection)
{
if (index++ == 0) continue;
var dataRow = dataTable.NewRow();
dataRow.ItemArray = (object[])item;
dataTable.Rows.Add(dataRow);
}
return new []{dataTable};
}
}
我在 nHibernate 中得到了一个查询结果:
var result = _Session.CreateSQLQuery("SELECT 'just a string' as Type, NAME FROM SCHEMA.PERSON where NAME like ('%A%')").List();
我想在 DataGridView 中显示此结果。所以我尝试了:
this.results.DataSource = result;
但这不起作用(它只显示了很多东西,如 "Length"、"Long Length"、"Rank" 等等,但不是实际的 sql 结果) 因为结果是类型: System.Collections.IList System.Collections.Generic.List 实际上看起来像 object 数组里面的 object 数组。
所以我尝试了:
this.results.DataSource = from res in result.Cast<List<object[]>>()
select new
{
T = res[0][0],
V = res[0][1]
};
但这只显示了一个空控件。
那么如何显示结果,作为一项高级任务,如何将 alias/select 结果名称显示为列 Headers?
顺便说一句。这应该适用于每个 SQL。所以我不能使用 mappingFiles.
经过这个问题的大量搜索和帮助:NHibernate output columns/projections of CreateQuery().list()
我找到了适合我的解决方案:
var query = _Session.CreateSQLQuery("SELECT 'just a string' as Type, NAME FROM SCHEMA.PERSON where NAME like ('%A%')").SetResultTransformer(Transformers.AliasToEntityMap);
var result = query.List();
var tab = new DataTable();
if (result.Count > 0)
{
var asHash = result[0] as Hashtable;
foreach (DictionaryEntry item in asHash)
{
tab.Columns.Add(item.Key as string);
}
foreach (Hashtable item in result)
{
var newobj = new Object[tab.Columns.Count];
int i = 0;
foreach (DictionaryEntry row in item)
{
newobj[i]= row.Value;
i++;
}
tab.Rows.Add(newobj);
}
}
this.results.DataSource = tab;
我确定还有其他(更好的)方法可以做到这一点,但是嘿:它有效。
其他解决方案不保留投影顺序。我实现了这个(丑陋的)数据转换器来保持顺序:
Usage example:
var command = "SELECT 'just a string' as Type, NAME FROM SCHEMA.PERSON where NAME like ('%A%')";
var query = _Session.CreateSQLQuery(command)
.SetResultTransformer(new DataTableTransformer());
var dataTable = (DataTable)query.List()[0];
Implementation:
public class DataTableTransformer : IResultTransformer
{
bool _isHeaderRowAdded;
public object TransformTuple(object[] tuple, string[] aliases)
{
if (false == _isHeaderRowAdded)
{
_isHeaderRowAdded = true;
return new Tuple<string[], object[]>(aliases, tuple);
}
return tuple;
}
public IList TransformList(IList collection)
{
if (collection.Count == 0)
{
return new []{new DataTable()};
}
var dataTable = new DataTable();
var headerAndFirstRow = (Tuple<string[], object[]>)collection[0];
foreach (var columnName in headerAndFirstRow.Item1)
{
dataTable.Columns.Add(columnName);
}
var newRow = dataTable.NewRow();
newRow.ItemArray = headerAndFirstRow.Item2;
dataTable.Rows.Add(newRow);
int index = 0;
foreach (var item in collection)
{
if (index++ == 0) continue;
var dataRow = dataTable.NewRow();
dataRow.ItemArray = (object[])item;
dataTable.Rows.Add(dataRow);
}
return new []{dataTable};
}
}