守候彩虹

我是风中的落叶,看我如何飞翔!
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

关于Nhibernate中One-to-many的一些疑惑

Posted on 2007-01-16 12:05  守候彩虹  阅读(1307)  评论(3编辑  收藏  举报
   园子里关于ORM的讨论好不热闹,我是一个新手,最近也开始学习Nhibernate,于是在园子里狂找了一些相关文章,其中DDLLYTerryLee张老三Aero无心之柳他们的东东给了我莫大的帮助,于是乎,我也就照着他们的例子自己照抄了一遍,呵呵,想满足满足自己的学习成就感,可不动手不知道,一动手可就发现了一大堆的问题,现在,我就把我学习中我觉得需要注意的一些问题贴出来,以供后来者少走弯路:

1.在写持久化类的映射文件时,需要把该文件设置为嵌入资源,这个在以上各位的文章中都反复强调到了。不过,我似乎发现这不是一个必要条件,他取决于你配置文件的设置和持久化类的装配方式,此问题有待近一步研究。

2.在手写映射文件时,将 nhibernate-mapping.xsd 文件拷贝到以下目录可以得到智能感知功能:
    a.vs2003:安装目录\Common7\Packages\schemas\xml
    b.vs2005: 安装目录\Xml\Schemas
    同样,在书写配置文件时,也可以将 nhibernate-configuration.xsd 文件如法炮制。

3.在书写映射文件时,需要在Class配置节中加入 lazy="false" 属性,对于lazy属性的意思,DDLLY是如下解释的:“lazy(可选):假若设置 lazy="true",就是设置这个类自己的名字作为proxy接口的一种等价快捷形式。” 不过,我还不太懂设置这个属性的意义,可能是还没用到的原因吧,还请高手能够指点迷津。

4.正确配置数据库,例如:
    a.如果在映射文件中对主键做如下配置:
1 <id type="Int32" column="child_id"  name="ChildId">
2     <generator class="identity" />
3 </id>
    那么,请务必在数据库中对该主键列设置为标识列。
    b.数据库字段是否为空的设置,如果某字段要求不为空,而在数据库持久化对象中又没有给相应属性赋值,那么,数据的CRUD操作就会不成功。
    以上两种情况在用NUnit在测试时都不会报错,但数据的插入等操作是不成功的。
5.做One-to-many关系时,在Parent(one一方)类需要定义一个Child类的集合,若配置文件如下书写:
1 <set name="Childs" cascade="all" inverse="true" >
2       <key column="parent_id" />      
        <one-to-many class="MediaSystem.Data.Child,MediaSystem.Data"/>
3 </set>
那么,在实体类中应如下定义该集合属性:
1 private ISet childs = new HashedSet();
2 public ISet Childs
3 {
4     get { return childs; }
5     set { childs = value; }
6 }
   
在以上张老三的 nhibernate入门系列: one-to-many映射 这篇文章中,是如下定义该集合属性的,但我做测试,没有成功。
1 private IDictionary childs = new Hashtable();
2 public IDictionary Childs 
3 {
4    get { return childs; }
5    set { childs = value; }
6 }
7 

一点疑惑(也就是困扰我一周的问题了,还请各为大虾帮帮我哈,我快崩溃了):
    在做
one-to-many关系时,网上文章的例子都是将主键设置为Int型的自增标识列,在映射文件中将generator的class属性设置为“identity”,我也这样试验了,没问题,但,我一把主键换成“guid”或者“assigend”就不正确了,不晓得为啥,其他的方式还没试过。废话少说,先贴代码。
另:在对string类型的属性赋值时,若字符串中有空格,好像也不能插入,不知原因。

Parent类:
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Collections;
 4 using System.Text;
 5 using Iesi.Collections;
 6 
 7 namespace MediaSystem.Data
 8 {
 9     public class Parent
10     {
11 
12         public Parent()
13         {
14         }
15 
16         public Guid ParentId
17         {
18             get { return parentId; }
19             set { parentId = value; }
20         }
21 
22         public string Name
23         {
24             get { return name; }
25             set { name = value; }
26         }
27 
28         public ISet Childs
29         {
30             get { return childs; }
31             set { childs = value; }
32         }
33 
34         private Guid parentId;
35         private string name;
36         private ISet childs = new HashedSet();
37 
38     } //class Parent
39 }
映射文件:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  
<class name="MediaSystem.Data.Parent, MediaSystem.Data" table="Parent" lazy="false">
      
<id type="Guid" column="parent_id"  name="ParentId">
        
<generator class="assigned" />
      
</id>
      
<property type="String" column="Name" name="Name"/>
     
<set name="Childs" cascade="all" inverse="true" >
      
<key column="parent_id" />
      
<one-to-many class="MediaSystem.Data.Child, MediaSystem.Data" />
    
</set>
    
</class>
</hibernate-mapping>
Child类:
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Text;
 4 
 5 namespace MediaSystem.Data
 6 {
 7     public class Child
 8     {
 9 
10         public Child()
11         {
12         }
13 
14         public Guid ChildId
15         {
16             get { return childId; }
17             set { childId = value; }
18         }
19 
20         public string Name
21         {
22             get { return name; }
23             set { name = value; }
24         }
25 
26         public Parent Parent
27         {
28             get
29             {
30                 if (parent == null) parent = new Parent();
31                 return parent;
32             }
33             set { parent = value; }
34         }
35 
36         private Guid childId;
37         private string name;
38         private Parent parent;
39 
40     } //class Child
41 }
child映射文件:
 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
 3   <class name="MediaSystem.Data.Child, MediaSystem.Data" table="Childs" lazy="false">
 4       <id type="Guid" column="child_id"  name="ChildId">
 5         <generator class="assigned" />
 6       </id>
 7       <property type="String" column="Name" name="Name"/>
 8       <many-to-one
 9          name="Parent"
10          column="parent_id"
11          class="MediaSystem.Data.Parent, MediaSystem.Data"
12          unique="true"
13    />
14     </class>
15   </hibernate-mapping>
测试代码:
 [Test]
        
public void TestCRUD()
        {
            Parent parent 
= new Parent();
            parent.ParentID = Guid.NewGuid();
       
            parent.Name = "testparent";

            
for (int i = 0; i < 10; i++)
            {
                Child child 
= new Child();

                child.Name = "testchild" + i.ToString() ;
                child.ChildID = Guid.NewGuid();
                child.Parent 
= parent;  
                parent.Childs.Add(child);
            }

           

            ISession session 
= NHHelper.Factory.OpenSession();
            session.Save(parent);
            session.Close();
        }
以上代码环境为:

1.IDE:vs2005
2.OS:window xp
3.Nhibernate:NHibernate-1.2.0.Beta2-debug