NHibernate 慎用IList

      今天在NHibernate群讨论着ISet怎样访问的时候,引申了一个问题,为什么要用ISet而不用IList呢?IList是多么的简单且自然。

    但是IList在处理重复的Item的时候也有不足,它是会插入重复的对象的,而ISet不会。因此在用IList做Mapping的时候,就有那么一点点不完美。

      先看Many-To-Many的例子,我们需要一个中间表,当一个IList增加同一个对象,IList.Count显示为2,数据库中间表会有两条相同的记录。如一个Child 有多个Parnet,Parent可能也有多个Child。代测试代码如下:    

 1: [TestMethod]
 2: public void ManyToManyTest()
 3: {
 4: var bf = new BurrowFramework();
 5: bf.InitWorkSpace();
 6:  
 7: var p = new Parent();
 8: var c1 = new Child { Name = "child1" };
 9: p.Children.Add(c1);
 10: p.Children.Add(c1);
 11:  
 12: Assert.AreEqual(2, p.Children.Count); //List 有两条记录
 13:  
 14: bf.GetSession().SaveOrUpdate(p);
 15:  
 16: bf.CloseWorkSpace();
 17: }

 

查看数据库结果.如下:

select * from dbo.LearnNHibernate_Parent_ChildRelation

ParentId ChildId
C0DAC4FA-079B-42BC-BEDC-7251655A6B9C 3117054E-8D1A-4C9D-93D4-7C6AFC715D65
C0DAC4FA-079B-42BC-BEDC-7251655A6B9C 3117054E-8D1A-4C9D-93D4-7C6AFC715D65

 

     对象的状态和数据库的状态是保持一致的,符合我对NHibernate预期。不过有什么业务有这样的需求呢?

     但是NHibernate处理one-to-many的时候,对象的状态和数据库的状态就不太相符了。请看代码:

 1: [TestMethod]
 2: public void OneToMany()
 3: {
 4: var bf = new BurrowFramework();
 5: bf.InitWorkSpace();
 6:  
 7: var p = new Director() { Name = "Director" };
 8: var c1 = new Student() { Name = "child1" };
 9: p.Students.Add(c1);
 10: p.Students.Add(c1);
 11:  
 12: Assert.AreEqual(2, p.Students.Count); //对象中Count为2
 13:  
 14: bf.GetSession().SaveOrUpdate(p);
 15:  
 16: bf.CloseWorkSpace();
 17:  
 18: }

     在内存中Direcotry是有两个Student对象的。那么数据库是怎样呢?其实不需要查看数据库,因为One-To-Many中,是不需要中间表的,只需要在Student表中提供Director的外键就可以了。换句话说,通过NHibernate,重新获取Director对像的时候,是不可能恢复到Director拥有2个相同的Student的状态。如果我期望有两个相同的对象,那么只好用Many-To-Many的方法了。

    总的来说,IList唯一的使用场景就是,一个对象可能拥有多个相同的子对象的时候。如果不是,还是用ISet比较方面,不需要为检查和移除重复对象付出的劳动力。不过这样的场景我真的没有见过,期望有哪位告知这样的场景。另外ISet不直接支持Linq,又不能用索引指示器(?),的确有点烦。

 源代码在这里

 

 

posted @ 2009-10-19 22:52  沉默的糕点  阅读(1161)  评论(0编辑  收藏  举报