我本来下载的是Castle RC2的MSI安装文件,并通过SVN下载了Generator,但是安装后发现了一些问题(主要是.net版本的问题),所以删除了之后,从SVN下载了全部最新的代码,然后用NAnt在.net 2.0环境下编译。
具体操作:
1,安装TortoiesSVN;
2,建立新目录:D:\working\Castle.SVN\
3,右击新建目录的图标,SVN CheckOut: http://svn.castleproject.org:8080/svn/castle/trunk/
(以下步骤参照下载下来的how to build.txt)
4,打开命令行,切换到D:\Working\Castle.SVN目录,执行命令: nant -t:net-2.0(当然前提是安装了NAnt)
这个过程比较长,持续了大约10分钟左右.最后生成了一个新目录: D:\working\Castle.SVN\build\net-2.0\debug .我们所需要引用的DLL就包含在这个目录里了(哪位能说一下怎么生成.net 2.0下的Release版?).
5,在本地的Sql Server上建立两个空数据库test, test2
第二步,尝试使用ActiveRecord.
这一步我基本上是跟着ActiveRecord Getting Started里的介绍在做,只不过没有使用VS的项目模板:
1,在Visual Studio 2005里新建一个Class Library项目,添加对以下dll的引用: Castle.ActiveRecord, Castle.Core, Castle.DynamicProxy, log4net, NHibernate.
2,录入代码:
School.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using Castle.ActiveRecord;
5
6 namespace BookStore.Components
7 {
8 [ActiveRecord("book_School")]
9 public class School : ActiveRecordBase<School>
10 {
11 Guid _id;
12 string _name;
13
14 IList<TClass> _classes = new List<TClass>();
15
16 [PrimaryKey(PrimaryKeyType.Guid)]
17 public Guid Id
18 {
19 get { return _id; }
20 set { _id = value; }
21 }
22
23 [Property]
24 public string Name
25 {
26 get { return _name; }
27 set { _name = value; }
28 }
29
30 [HasMany(typeof(TClass), Inverse = true, Cascade = ManyRelationCascadeEnum.AllDeleteOrphan)]
31 public IList<TClass> Classes
32 {
33 get { return _classes; }
34 set { _classes = value; }
35 }
36 }
37 }
38
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using Castle.ActiveRecord;
5
6 namespace BookStore.Components
7 {
8 [ActiveRecord("book_School")]
9 public class School : ActiveRecordBase<School>
10 {
11 Guid _id;
12 string _name;
13
14 IList<TClass> _classes = new List<TClass>();
15
16 [PrimaryKey(PrimaryKeyType.Guid)]
17 public Guid Id
18 {
19 get { return _id; }
20 set { _id = value; }
21 }
22
23 [Property]
24 public string Name
25 {
26 get { return _name; }
27 set { _name = value; }
28 }
29
30 [HasMany(typeof(TClass), Inverse = true, Cascade = ManyRelationCascadeEnum.AllDeleteOrphan)]
31 public IList<TClass> Classes
32 {
33 get { return _classes; }
34 set { _classes = value; }
35 }
36 }
37 }
38
TClass.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using Castle.ActiveRecord;
5
6 namespace BookStore.Components
7 {
8 [ActiveRecord("book_class")]
9 public class TClass : ActiveRecordBase<TClass>
10 {
11 Guid _id;
12 string _name;
13 int _birthYear;
14
15 School _school;
16
17 [PrimaryKey(PrimaryKeyType.Guid)]
18 public Guid Id
19 {
20 get { return _id; }
21 set { _id = value; }
22 }
23
24 [Property]
25 public int BirthYear
26 {
27 get { return _birthYear; }
28 set { _birthYear = value; }
29 }
30
31 [Property]
32 public string Name
33 {
34 get { return _name; }
35 set { _name = value; }
36 }
37
38 [BelongsTo("schoolId")]
39 public School School
40 {
41 get { return _school; }
42 set { _school = value; }
43 }
44 }
45 }
46
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using Castle.ActiveRecord;
5
6 namespace BookStore.Components
7 {
8 [ActiveRecord("book_class")]
9 public class TClass : ActiveRecordBase<TClass>
10 {
11 Guid _id;
12 string _name;
13 int _birthYear;
14
15 School _school;
16
17 [PrimaryKey(PrimaryKeyType.Guid)]
18 public Guid Id
19 {
20 get { return _id; }
21 set { _id = value; }
22 }
23
24 [Property]
25 public int BirthYear
26 {
27 get { return _birthYear; }
28 set { _birthYear = value; }
29 }
30
31 [Property]
32 public string Name
33 {
34 get { return _name; }
35 set { _name = value; }
36 }
37
38 [BelongsTo("schoolId")]
39 public School School
40 {
41 get { return _school; }
42 set { _school = value; }
43 }
44 }
45 }
46
由于个人更喜欢Guid类型的主键,所以没有完全照搬教程的代码,而是做了一些修改.
编译,通过.好了,下一步写点测试代码吧.
Getting Started里用的是Winform,我顺便改成了使用NUnit的测试.
SchoolTest.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using NUnit.Framework;
5 using Castle.ActiveRecord;
6 using Castle.ActiveRecord.Framework.Config;
7 using BookStore.Components;
8
9 namespace BookStore.Tests
10 {
11 [TestFixture]
12 public class SchoolClass
13 {
14 [TestFixtureSetUp]
15 public void SetUpAll()
16 {
17 XmlConfigurationSource source = new XmlConfigurationSource("appconfig.xml");
18
19 ActiveRecordStarter.Initialize(source, typeof(School), typeof(TClass));
20
21 ActiveRecordStarter.CreateSchema();
22 school = new School();
23 school.Name = schoolName;
24 school.Create();
25 }
26
27 School school;
28 string schoolName = "中国矿业大学(北京)";
29
30 [Test]
31 public void Schools()
32 {
33 Assert.AreEqual(1, School.FindAll().Length);
34 School newSchool = School.Find(school.Id);
35 Assert.AreEqual(school.Id, newSchool.Id);
36 Assert.AreEqual(schoolName, newSchool.Name);
37 }
38
39 [Test]
40 public void Classses()
41 {
42 string className="市场管理001班";
43 TClass theClass = new TClass();
44 theClass.Name = className;
45 theClass.School = school;
46 theClass.BirthYear = 2000;
47 theClass.Create();
48
49 Assert.AreEqual(1, TClass.FindAll().Length);
50 TClass newClass = TClass.Find(theClass.Id);
51 Assert.AreEqual(theClass.Id, newClass.Id);
52 Assert.AreEqual(className, newClass.Name);
53 Assert.AreEqual(schoolName, newClass.School.Name);
54 Assert.AreEqual(2000, newClass.BirthYear);
55 }
56
57 [TestFixtureTearDown]
58 public void TearDown()
59 {
60 ActiveRecordStarter.DropSchema();
61 }
62 }
63 }
64
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using NUnit.Framework;
5 using Castle.ActiveRecord;
6 using Castle.ActiveRecord.Framework.Config;
7 using BookStore.Components;
8
9 namespace BookStore.Tests
10 {
11 [TestFixture]
12 public class SchoolClass
13 {
14 [TestFixtureSetUp]
15 public void SetUpAll()
16 {
17 XmlConfigurationSource source = new XmlConfigurationSource("appconfig.xml");
18
19 ActiveRecordStarter.Initialize(source, typeof(School), typeof(TClass));
20
21 ActiveRecordStarter.CreateSchema();
22 school = new School();
23 school.Name = schoolName;
24 school.Create();
25 }
26
27 School school;
28 string schoolName = "中国矿业大学(北京)";
29
30 [Test]
31 public void Schools()
32 {
33 Assert.AreEqual(1, School.FindAll().Length);
34 School newSchool = School.Find(school.Id);
35 Assert.AreEqual(school.Id, newSchool.Id);
36 Assert.AreEqual(schoolName, newSchool.Name);
37 }
38
39 [Test]
40 public void Classses()
41 {
42 string className="市场管理001班";
43 TClass theClass = new TClass();
44 theClass.Name = className;
45 theClass.School = school;
46 theClass.BirthYear = 2000;
47 theClass.Create();
48
49 Assert.AreEqual(1, TClass.FindAll().Length);
50 TClass newClass = TClass.Find(theClass.Id);
51 Assert.AreEqual(theClass.Id, newClass.Id);
52 Assert.AreEqual(className, newClass.Name);
53 Assert.AreEqual(schoolName, newClass.School.Name);
54 Assert.AreEqual(2000, newClass.BirthYear);
55 }
56
57 [TestFixtureTearDown]
58 public void TearDown()
59 {
60 ActiveRecordStarter.DropSchema();
61 }
62 }
63 }
64
测试,OK!
需要注意的几点:
1,ActiveRecord里主键默认是int类型,改成Guid之后,PrimaryKey属性必须声明为[PrimaryKey(PrimaryKeyType.Guid)],否则进行数据库操作时会出错.
2,ActiveRecord里主键不应该被赋值,即使赋值了添加到数据库时也会因为重新生成主键而丢失.
3,这个版本的ActiveRecordStarter.CreateSchemaFromFile好像有点问题,执行后没有任何效果,而且不报任何错误.