您的位置:首页 > 其它

NHibernate in Action ch2 Hello NHibernate 读后

2011-07-30 09:35 323 查看
(一)对象的标识以及Database到Object的映射

If two instances of Employee have the same identifier value, they represent the same row in the database。

这里指的是如果两个对象具有同样的ID,那么他们代表数据库中的同一行。也就是说这是Database到Object映射的一个维度,是通过ROWID来完成对象级别的映射的。

Q:那么因此对Object的Compare来说,是否需要需要重写Equals方法?NHibernate会默认重写Object的Equals方法么或者提供对象的Compare方法?
A:   仍然需要。在Test的代码中,采用同一个ID从Session中获取Object的时候,此时Make Object ID发现获取的Object是一样的,这是由于NH对Object的Cache导致的,所以等采用同一个ID从不同的Session中获取Object的时候发现此时是不一样的。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
  [TestCase]
        public void TestObjectThatGetsFromSessionAreEqual()
        {
            const string strName = "Test";
            Employee employee = new Employee();
            employee.Name = strName;
 
            Employee employeeCompare = new Employee();
            employeeCompare.Name = "employeeComare.Name";
 
            Assert.AreNotEqual(employeeCompare, employee);
 
            using (ISession session = OpenSession())
            {
                using (ITransaction tx = session.BeginTransaction())
                {
                    session.Save(employee);
                    session.Save(employeeCompare);
                    tx.Commit();
                }              
 
            }
 
            int id = employee.ID;
          
            using (ISession session = OpenSession())
            {
                employee = session.Get<Employee>(id);
                 var employeeCompareFromSameSession = session.Get<Employee>(id);
                 Assert.AreEqual(employee, employeeCompareFromSameSession);
                 Assert.AreSame(employee, employeeCompareFromSameSession);
            }
 
            using (ISession session = OpenSession())
            {
                employeeCompare = session.Get<Employee>(id);              
                Assert.AreNotEqual(employee, employeeCompare, "They are not equal");
                Assert.AreNotSame(employee, employeeCompare);
            }
 
        }
 
Q: 如果使用同一ID去获取对象,这两个对象是Reference Equal么?如果不是,NH就可能每次都去数据库取一次了,如果是,比如存在缓存。
A:示例如上所示,由于Session的cache 的作用,这两个是Reference Equal的。

Q: 改变一个Object的ID会产生什么影响?
A:    此时会抛出来异常。failed: NHibernate.HibernateException : identifier of an instance of HelloNH.Employee was altered from 23 to 2222
       另外如果在代码中设置了Object的ID的话,NH仍然会按照自己的思路修改这个ObjectID,只要Object纳入了Session的管理中,那么异常就会抛出来。其实看一下调用的堆栈卡可以猜测,NH通过一系列的事件来管理起来所有的Object了,任何对Object的修改都会触发事件响应。
代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        [TestCase]
        public void TestChangeObjectID()
        {
            Assert.Catch<HibernateException>(
            delegate{           
            Employee e = new Employee() { Name = "Employeee name" };
            e.ID = 1111;
            using (ISession sesion = OpenSession())
            {
                using (ITransaction tx = sesion.BeginTransaction())
                {
                    sesion.Save(e);
                    //此?时骸?已?经-抛×出?来ぁ?异馬?常£了?
                    e.ID = 2222;
                    tx.Commit();
                    e.ID = 5555;
                }
            }
            });
        }
作者说"Instances of the Employee class may be managed(made persistent) by NHibernate", 呵呵,用了个May Be。

Q: 如果传过来的Object为NULL, NHibernate会怎么出来?报错么?我觉得会报错。处理方式有两种么:跳过,或者报错。报错能让我知道结果。

A:报错. attempt to create saveOrUpdate event with null entity。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: