Hql的select 语句返回Ilist<object[]>类型,如何转换为映射类型。
(一)持久类
public class Customer
{
public virtual int Unid { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
}
(二)hql
var xx =_Session.CreateQuery("select Unid,FirstName,LastName from Customer").List<object[]>();
其中xx的类型为object[]数组的泛型列表类型。
现在分解:
(1)方法1
IList<Customer> mylist = new List<Customer>();
for (int i = 0; i < xx.Count; i++)
{
mylist.Add(new Customer
{ FirstName = (string)xx[i][1],
LastName = (string)xx[i][2],
Unid = Convert.ToInt32(xx[i][0])
});
}
说明:object[]数组包括了对持久类的3个属性的装箱,分别对应
Unid(int-object);FirstName(string-object);LastName(string-object)
通过拆箱来还原持久类
(2)方法2
把持久类的3个属性的拆箱封装为方法。
public Customer GetCustomer(object[] aa)
{
return new Customer
{
FirstName = (string)aa[1],
LastName = (string)aa[2],
Unid = Convert.ToInt32(aa[0]
)};
}
for (int i = 0; i < xx.Count; i++)
{
mylist.Add(GetCustomer(xx[i]));
}
(3)方法3
利用Converter 泛型委托(表示将对象从一种类型转换为另一种类型的方法。)
相关帮助请查看其它文档。
List<Customer> clist=new List<Customer>();
clist = xx.ConvertAll<Customer>(new Converter<object[], Customer>(GetCustomerr));
委托方法:
public Customer GetCustomerr(object[] aa)
{
return new Customer
{
FirstName = (string)aa[1],
LastName = (string)aa[2],
Unid = Convert.ToInt32(aa[0]
)};
}
会发现方法2中的封装方法与方法3中的委托是相关的!
请大家使用第三种方法。
再以select group by 为例子。
此图为在mssql查询分析器中对目录的Customer表中的数据进行以firstname分组的列表,并显示统计数目
public List<Customer> ShowSelectGroup()
{
List<object[]> xx = _Session.CreateQuery
("select FirstName,count(*) from Customer group by FirstName")
.List<object[]>() as List<object[]>;
List<Customer> clist = new List<Customer>();
clist = xx.ConvertAll<Customer>(
new Converter<object[], Customer>(GetCustomerGroup)
);
return clist;
}
用第三种方法实现到持久类型的转换。
说明一下:此分组查询有两列,分别是FirstName列,与未命名的统计列。其中一个为string 类型,一种为int类型(简化考虑:长度,与其它不考虑)。
那种如果要转换,则需要一种带2个属性的类。这里我还用Customer持久类。但不是用它的所有属性,只用它的FirstName属性和Unid属性(这里Customer类已经不存在它的意义)。
重新定义委托方法:
public Customer GetCustomerGroup(object[] aa)
{
return new Customer {
FirstName = (string)aa[0],
Unid = Convert.ToInt32(aa[1]
)};
}
测试一下:
------ Test started: Assembly: SelfTest.dll ------
Jimmy1:1
Tom:3
zsj:3
zzy:1
1 passed, 0 failed, 0 skipped, took 6.13 seconds (NUnit 2.5.0).
--补充内容
(1)定义实体类(用于构建List类型,来封装返回的数据)
public class CustomerDTO
{
public CustomerDTO(string fri,string las)
{}
public string FirstName { get; set; }
public string LastName { get; set; }
}
(2)利用上边的实体类型返回实体类型的List列表
var xx =_Session.CreateQuery("select new CustomerDTO(c.FirstName,c.LastName) from Customer c")
.List<CustomerDTO>();
注:引自Lee(李永京)的讲解,更多内容请参见他的博客。
http://www.cnblogs.com/lyj/archive/2008/10/30/1323099.html
-------over