如何在 DataGridView 中显示 nHibernate CreateSQLQuery 的结果?

Posted

技术标签:

【中文标题】如何在 DataGridView 中显示 nHibernate CreateSQLQuery 的结果?【英文标题】:How to show the result of nHibernate CreateSQLQuery in DataGridView? 【发布时间】:2019-07-16 11:34:25 【问题描述】:

我在 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;

但这不起作用(它只显示了很多东西,如“长度”、“长长度”、“等级”等等,但没有显示实际的 sql 结果),因为结果类型为:System.Collections。 IList System.Collections.Generic.List 实际上看起来像是对象数组中的对象数组。

所以我尝试了:

this.results.DataSource = from res in result.Cast<List<object[]>>()
                          select new
                          
                              T = res[0][0],
                              V = res[0][1]
                          ;

但这仅显示一个空控件。

那么如何显示结果以及如何将别名/选择结果名称显示为列标题作为一项高级任务?

顺便说一句。这应该适用于每个 SQL。所以我不能使用mappingFiles。

【问题讨论】:

使用填充数据表的 SQLDataAdapter。然后将数据表作为 DGV 的来源。见 msdn:docs.microsoft.com/en-us/dotnet/api/… @jdweng:这似乎不适用于 nhibernate 会话... 查询返回 List。所以你可以使用方法 DataTable dt = result.CopyToDataTable();然后让datatable成为DGV datagridview1.DataSource = dt;的来源 但是只要 SQLDataAdapter 不能与 nHibernate 会话一起工作,这对我没有帮助... 查看源代码它看起来不像DataSet方法使用了DataAdapter。它将 DataRow 列表复制到 DataSet 中。 【参考方案1】:

经过大量搜索和这个问题的帮助: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; 

我确信还有其他(更好的)方法可以做到这一点,但是嘿:它有效。

【讨论】:

此解决方案不保留列顺序,如果您想使用自动列绑定,这是一个问题。【参考方案2】:

其他解决方案不保留投影顺序。我实现了这个(丑陋的)数据转换器来保持顺序:

        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;
            
        

【讨论】:

以上是关于如何在 DataGridView 中显示 nHibernate CreateSQLQuery 的结果?的主要内容,如果未能解决你的问题,请参考以下文章

插入后如何在datagridview中立即刷新或显示?

如何在datagridview中显示两个人之间的关系

如何在 C# 中获取 dataGridView 中所有 Combobox 列的显示成员?

如何在 DataGridView 中显示 nHibernate CreateSQLQuery 的结果?

如何在 datagridview 中显示图像? C#

插入后如何在datagridview中立即刷新或显示?