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

时间:2019-02-22 11:20:51

标签: c# sql sql-server nhibernate 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,实际上看起来像是对象数组内部的对象数组。

所以我尝试了:

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

但这仅显示一个空控件。

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

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

2 个答案:

答案 0 :(得分:0)

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

我敢肯定还有其他(更好)的方法,但是,嘿:它可行。

答案 1 :(得分:0)

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

        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};
            }
        }