园子里关于ORM的讨论好不热闹,我是一个新手,最近也开始学习Nhibernate,于是在园子里狂找了一些相关文章,其中DDLLY,TerryLee,张老三,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是如下解释的:“
4.正确配置数据库,例如:
a.如果在映射文件中对主键做如下配置:
b.数据库字段是否为空的设置,如果某字段要求不为空,而在数据库持久化对象中又没有给相应属性赋值,那么,数据的CRUD操作就会不成功。
以上两种情况在用NUnit在测试时都不会报错,但数据的插入等操作是不成功的。
5.做One-to-many关系时,在Parent(one一方)类需要定义一个Child类的集合,若配置文件如下书写:
一点疑惑(也就是困扰我一周的问题了,还请各为大虾帮帮我哈,我快崩溃了):
在做one-to-many关系时,网上文章的例子都是将主键设置为Int型的自增标识列,在映射文件中将generator的class属性设置为“identity”,我也这样试验了,没问题,但,我一把主键换成“guid”或者“assigend”就不正确了,不晓得为啥,其他的方式还没试过。废话少说,先贴代码。
另:在对string类型的属性赋值时,若字符串中有空格,好像也不能插入,不知原因。
Parent类:
1.IDE:vs2005
2.OS:window xp
3.Nhibernate:NHibernate-1.2.0.Beta2-debug
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>
那么,请务必在数据库中对该主键列设置为标识列。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>
那么,在实体类中应如下定义该集合属性:
在以上张老三的 nhibernate入门系列: one-to-many映射 这篇文章中,是如下定义该集合属性的,但我做测试,没有成功。
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 }
2 public ISet Childs
3 {
4 get { return childs; }
5 set { childs = value; }
6 }
1 private IDictionary childs = new Hashtable();
2 public IDictionary Childs
3 {
4 get { return childs; }
5 set { childs = value; }
6 }
7
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 }
映射文件: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类:<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>
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映射文件: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 }
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>
测试代码: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();
}
以上代码环境为: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