NHibernate Issues之1904/1905:相同属性的Domain与Join查询/子查询
概览这个系列是以博客形式整理关于NHibernate的Issues。记录一些零碎的小例子通过零零碎碎的整理可以巩固自己的知识和扩展我们的知识面。这些小例子也可以适当的在项目中呈现。在接下来的NHibernate2.1.1GA版本中修正了两个BUG。分别是[NH-1904]和[NH-1905]之所以提出来我原来也用过这样的情况但是始终无解看了这两个链接原来是BUG现在我们可以用了~~两个实例实例一如果Domain中没有什么业务逻辑一般都是使用“贫血模型”但是有的为了需要增加一些业务逻辑就慢慢形成了“充血模型”这篇暂且不谈它们之间的优缺点。我有时使用“充血模型”需要在Domain中定义一些“保护的或者私有的”属性满足一些逻辑有时也需要两个相同的属性不同的权限互相赋值什么的但是这一点NHibernate都不支持因为是通过映射来找属性的根据属性命名算法有着不同的访问策略无奈之下只有使用别的别名代替。1.Domain模拟一Domain有两个(几乎)相同的属性一个是公共的一个是保护的。我们操作公共的属性必要的时候赋值给那个保护的。public class Invoice { public virtual int Id { get; private set; } public virtual DateTime Issued { get; set; } protected virtual DateTime issued { get; set; } }2.Mapping映射这个Domain这里就映射公共的那个属性用于持久化吧class nameInvoice id nameId generator classhilo / /id property nameIssued/ /class3.Test验证下Save和查询方法。OKusing (var session OpenSession()) using (var transaction session.BeginTransaction()) { var invoice new Invoice {Issued DateTime.Now}; session.Save(invoice); transaction.Commit(); } using (var session OpenSession()) { var invoices session.CreateCriteriaInvoice().ListInvoice(); }实例二在我们的项目中错综复杂的关系经常需要Join查询和子查询但是Join查询我们都在在映射文件中配置关系如果没有配置关系NHibernate的Join查询就无能为力了只有Select两张表然后让两张表的Id相等。这好像是linq to sql的一贯做法。NHibernate在这点上强了很多只要在映射文件中配置一下小小查询什么都搞定了。1.Domain三个DomainMasterDetailsElementMaster与Elements多对多关系Detail与Master多对一关系。public class Master { public virtual int Id { get; set; } public virtual ISetElement Elements { get; set; } } public class Detail { public virtual int Id { get; set; } public virtual Master Master { get; set; } } public class Element { public virtual int Id { get; set; } public virtual string Description { get; set; } }2.Mapping映射这个Domain。class nameMaster id nameId generator classassigned / /id set nameElements tableMasterElement key columnMasterId / many-to-many columnElementId classElement/ /set /class class nameDetail id nameId generator classassigned / /id many-to-one nameMaster classMaster columnMasterId / /class class nameElement id nameId generator classassigned / /id property nameDescription/ /class3.Test我的目的是要查询Detail信息Join关联他的Master还有个子查询判断Master的Elements描述信息e1的数量大于0。下面这句比较经典了。var det s.CreateQuery(from Detail d left join d.Master m where (select count(e) from d.Master.Elements e where e.Descriptione1)0) .ListDetail();