找回密码
 立即注册
首页 业界区 业界 NHibernate拾贝1904/1905:相同属性的Domain与Join查询/ ...

NHibernate拾贝1904/1905:相同属性的Domain与Join查询/子查询

呼延含玉 2025-5-29 14:58:20
本节内容
           
  • 概览       
  • 两个实例       
  • 参考资料
概览

这个系列是以博客形式整理关于NHibernate的Issues。记录一些零碎的小例子,通过零零碎碎的整理,可以巩固自己的知识和扩展我们的知识面。这些小例子也可以适当的在项目中呈现。
在接下来的NHibernate2.1.1GA版本中,修正了两个BUG。分别是[NH-1904]和[NH-1905],之所以提出来,我原来也用过这样的情况,但是始终无解,看了这两个链接,原来是BUG,现在我们可以用了~~
两个实例

实例一

如果Domain中没有什么业务逻辑,一般都是使用“贫血模型”,但是有的为了需要增加一些业务逻辑,就慢慢形成了“充血模型”,这篇暂且不谈它们之间的优缺点。我有时使用“充血模型”,需要在Domain中定义一些“保护的或者私有的”属性满足一些逻辑,有时也需要两个相同的属性不同的权限互相赋值什么的,但是这一点NHibernate都不支持(因为是通过映射来找属性的,根据属性命名算法有着不同的访问策略),无奈之下只有使用别的别名代替。
1.Domain

模拟一Domain,有两个(几乎)相同的属性,一个是公共的,一个是保护的。我们操作公共的属性,必要的时候赋值给那个保护的。
  1. public class Invoice
  2. {
  3.     public virtual int Id { get; private set; }
  4.     public virtual DateTime Issued { get; set; }
  5.     protected virtual DateTime issued { get; set; }
  6. }
复制代码
2.Mapping

映射这个Domain,这里就映射公共的那个属性用于持久化吧
  1. <class name="Invoice">
  2.     <id name="Id">
  3.         <generator class="hilo" />
  4.     </id>
  5.     <property name="Issued"/>
  6. </class>
复制代码
3.Test

验证下Save和查询方法。OK
  1. using (var session = OpenSession())
  2. using (var transaction = session.BeginTransaction())
  3. {
  4.     var invoice = new Invoice {Issued = DateTime.Now};
  5.     session.Save(invoice);
  6.     transaction.Commit();
  7. }
  8. using (var session = OpenSession())
  9. {
  10.     var invoices = session.CreateCriteria<Invoice>().List<Invoice>();
  11. }
复制代码
实例二

在我们的项目中,错综复杂的关系经常需要Join查询和子查询,但是Join查询我们都在在映射文件中配置关系,如果没有配置关系NHibernate的Join查询就无能为力了,只有Select两张表,然后让两张表的Id相等。这好像是linq to sql的一贯做法。NHibernate在这点上强了很多,只要在映射文件中配置一下,小小查询什么都搞定了。
1.Domain

三个Domain:Master,Details,Element,Master与Elements多对多关系,Detail与Master多对一关系。
  1. public class Master
  2. {
  3.     public virtual int Id { get; set; }
  4.     public virtual ISet<Element> Elements { get; set; }
  5. }
  6. public class Detail
  7. {
  8.     public virtual int Id { get; set; }
  9.     public virtual Master Master { get; set; }
  10. }
  11. public class Element
  12. {
  13.     public virtual int Id { get; set; }
  14.     public virtual string Description { get; set; }
  15. }
复制代码
2.Mapping

映射这个Domain。
  1. <class name="Invoice">
  2.     <id name="Id">
  3.         <generator class="hilo" />
  4.     </id>
  5.     <property name="Issued"/>
  6. </class><class name="Invoice">
  7.     <id name="Id">
  8.         <generator class="hilo" />
  9.     </id>
  10.     <property name="Issued"/>
  11. </class><class name="Invoice">
  12.     <id name="Id">
  13.         <generator class="hilo" />
  14.     </id>
  15.     <property name="Issued"/>
  16. </class><class name="Invoice">
  17.     <id name="Id">
  18.         <generator class="hilo" />
  19.     </id>
  20.     <property name="Issued"/>
  21. </class>   
复制代码
3.Test

我的目的是要查询Detail信息,Join关联他的Master,还有个子查询判断Master的Elements描述信息e1的数量大于0。下面这句比较经典了。
  1. var det= s.CreateQuery(@"from Detail d left join d.Master m
  2.      where (select count(e) from d.Master.Elements e where e.Description='e1')>0")
  3.     .List<Detail>();
复制代码
参考资料

NHibernate Jira:Protected properties and public properties cannot have the same name with different case
NHibernate Jira:Join used together with subquery generates wrong SQL

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册