Nhibnate之CreateQuery和CreateSqlQuery查询
在N'hibnate中,提供了多种查询方法。这里主要介绍两种:HQl查询和SQl查询。
一。Nhibnate支持的HQl查询方式。例如句:select h.SeqId from LeaseUser。该查询语句中,LeaseUser是实体对象,而SeqId是实体中的属性。因为查询对象是实体,所以可以直接返回对应的实体属性值或实体对象。
1.1.返回实体属性值。list<T>:T指代具体返回的属性类型。
1 public static void Main(string[] args) 2 { 3 //NHibernateProfiler程序分析初始化 4 //HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); 5 ISessionFactory factory = new Configuration().Configure().BuildSessionFactory(); 6 ISession session = factory.OpenSession(); 7 using (ITransaction rs = session.BeginTransaction()) 8 { 9 var km = session.CreateQuery("select SeqId from LeaseUserBankCard").List<int>(); 10 var kms = session.CreateQuery("select BankName from LeaseUserBankCard").List<string>(); 11 }
1.2.返回具体的实体对象。在HQL中,使用*,是会报异常的,需要注意。如果返回所有属性,不能用*代替。句式应如:from LeaseUser where <过滤条件>
1 public static void Main(string[] args) 2 { 3 //NHibernateProfiler程序分析初始化 4 //HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); 5 ISessionFactory factory = new Configuration().Configure().BuildSessionFactory(); 6 ISession session = factory.OpenSession(); 7 using (ITransaction rs = session.BeginTransaction()) 8 { 9 10 var bm = session.CreateQuery("select * from LeaseUserBankCard") 11 .List<LeaseUserBankCard>();//Error:NHibernate.Hql.Ast.ANTLR.QuerySyntaxException:“A recognition error occurred. near line 1, column 7” 12 var bms = session.CreateQuery("from LeaseUserBankCard where SeqId=:ts") 13 .SetParameter("ts", 20).List<LeaseUserBankCard>();//使用了命名型参数形式 14 } 15 }
二。使用原生的SQL语句,例如:select h.seq_id from lease_user h。查询语句中,lease_user是具体的表名,而seq_id是表字段名。在原生sql中,查询的是数据库表和字段。所以不能返回对应的实体属性和实体对象,需要处理。
2.1 返回属性值。原生sql返回的是数据库类型,需要转换成NHibnate类型,使用方法AddScalar(),指定返回的字段NHibnate类型.
1 public static void Main(string[] args) 2 { 3 //NHibernateProfiler程序分析初始化 4 //HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); 5 ISessionFactory factory = new Configuration().Configure().BuildSessionFactory(); 6 ISession session = factory.OpenSession(); 7 using (ITransaction rs = session.BeginTransaction()) 8 { 9 //直接返回指定字段值 10 var nk = session.CreateSQLQuery("select seq_id from lease_user") 11 .List<int>();//Error:System.ArgumentException:“值“36”不是“System.Int32”类型,不能在此泛型集合中使用。 12 var nk2 = session.CreateSQLQuery("select seq_id from lease_user where seq_id=:ps") 13 .AddScalar("seq_id", NHibernateUtil.Int32) 14 .SetParameter("ps", 36).List<int>();//AddScalar转换字段类型
2.2。返回具体的对象。使用AddEntity(entityName)方法实现,要注意的是entityName必须是全限定的实体名称,否则异常。
1 using (ITransaction rs = session.BeginTransaction()) 2 { 3 //直接具体的实体对象。AddEntity中的实体名称必须是全限定名称, 4 //否则异常:NHibernate.MappingException:“No persister for: LeaseUser” 5 var nb = session.CreateSQLQuery("select seq_id from lease_user where user_name=:ps") 6 .AddEntity("LeaseUser") 7 .SetParameter("ps", "包磊").List<int>();//
1 using (ITransaction rs = session.BeginTransaction()) 2 { 3 //直接具体的实体对象。AddEntity中的实体名称必须是全限定名称,获取具体实体的三种实现方式如下 4 var nb = session.CreateSQLQuery("select * from lease_user where user_name=:ps") 5 .AddEntity("Domain.Entity.LeaseUser") 6 .SetParameter("ps", "包磊").List<LeaseUser>(); 7 8 var nb2 = session.CreateSQLQuery("select * from lease_user where user_name=:ps") 9 .AddEntity(typeof(LeaseUser)) 10 .SetParameter("ps", "包磊").List<LeaseUser>(); 11 12 var nb3 = session.CreateSQLQuery("select * from lease_user u where user_name=:ps") 13 .AddEntity("u", typeof(LeaseUser)) 14 .SetParameter("ps", "包磊").List<LeaseUser>(); 15 }
2.3 关联关系查询AddJoin.使用该方法的前提是在xml映射配置中,做了关联关系。如一对一,多对一的关系。
1 public class LeaseUser 2 { 3 public virtual LeaseUserBankCard BankCard { get; set; } 4 }
一对一关系:
<many-to-one name="BankCard" class="LeaseUserBankCard" column="OWNER_ID" unique="true"/>
1 using (ITransaction rs = session.BeginTransaction()) 2 { 3 var joinUser = session.CreateSQLQuery(@"select h.*,mb.* from lease_user h 4 left join lease_user_bank_card mb on mb.owner_id=h.seq_id 5 where h.user_name=:ps") 6 .AddEntity("h",typeof(LeaseUser)) 7 .AddJoin("mb", "h.BankCard")//BankCard是定义在实体LeaseUser中的属性,类型为LeaseUserBankCard。在LeaseUser.hbm.xml中做了配置一对一关系映射 8 .SetParameter("ps","包磊").List(); 9 session.Close(); 10 Console.ReadLine(); 11 }
2.3 返回多个实体
1 using (ITransaction rs = session.BeginTransaction()) 2 { 3 var entitys = session.CreateSQLQuery(@"select h.*,mb.* from lease_user h 4 left join lease_user_bank_card mb on mb.owner_id=h.seq_id 5 where h.user_name=:ps") 6 .AddEntity("h", typeof(LeaseUser)) 7 .AddEntity("mb", typeof(LeaseUserBankCard)) 8 .SetParameter("ps", "包磊") 9 .List(); 10 }
2.4 返回非受管实体。可以对原生sql查询执行IResuleTransformer。这会返回不受Hibernate管理的实体。如自定义一个dto类。
1 public class LeaseUserDTO 2 { 3 public int? Seq_id { get; set; } 4 5 public string Card_No { get; set; } 6 7 public string User_Name { get; set; } 8 9 public string BANK_CARD_NO { get; set; } 10 }
1 using (ITransaction rs = session.BeginTransaction()) 2 { 3 4 //返回非NHibernate管理的实体,LeaseUserDTO将被实体化,同时将查询字段值注射入LeaseUserDT对应的属性和字段中 5 var entitys2 = session.CreateSQLQuery(@"select h.Seq_id,h.Card_No,h.User_Name,mb.BANK_CARD_NO from lease_user h 6 left join lease_user_bank_card mb on mb.owner_id=h.seq_id 7 where h.user_name=:ps") 8 .AddScalar("Seq_id", NHibernateUtil.Int32) 9 .AddScalar("Card_No", NHibernateUtil.String) 10 .AddScalar("User_Name", NHibernateUtil.String) 11 .AddScalar("BANK_CARD_NO", NHibernateUtil.String) 12 .SetParameter("ps", "包磊") 13 .SetResultTransformer(Transformers.AliasToBean(typeof(LeaseUserDTO))) 14 .List(); 15 }
生命需要感动和奇迹。成功不易,放弃简单。每次感觉走不下去的时候,就是通往成功的节点。努力吧,奋斗吧,即使不被全世界看好。至少,也要做个坏孩子啊