摘要:前面几篇文章简单的介绍了ActiveRecord中的基本映射以及构建配置信息,本文我们用ActiveRecord里面的Blog,Post例子来实现One-Many/Many-One关联。
主要内容
1.准备数据表结构
2.编写实体类并介绍HasMany和BlongsTo特性
3.构建配置信息
4.编写测试代码
一.准备数据表结构
在这个例子中,我们引入了两个对象Blog、Post,它们之间的关系是一对多,即一个Blog有多篇Post。需要用到的数据表结构如下
CREATE TABLE Blogs (

blog_id int IDENTITY(1, 1) PRIMARY KEY,

blog_name varchar(50),

blog_author varchar(50)

)


CREATE TABLE Posts (

post_id int IDENTITY(1, 1) PRIMARY KEY,

post_title varchar(50),

post_contents text,

post_categories varchar(50),

post_blogid int FOREIGN KEY REFERENCES Blogs (blog_id),

post_created datetime,

post_published bit

)
二.编写实体类
首先我们来看Blog实体类的编写,需要用到HasMany特性,这时我们会在Blog实体类中定义一个Posts属性,用它来表示该Blog所发表的所有Posts,代码如下
[ActiveRecord("Blogs")]

public class Blog : ActiveRecordBase



{

//……

private IList _posts;


[HasMany(typeof(Post), Table="posts", ColumnKey="post_blogid")]

public IList Posts


{


get
{ return _posts; }


set
{ _posts = value; }

}

}
HasManyAttribute说明
|
属性
|
说明
|
示例
|
|
Cascade
|
指明哪些操作会从父对象级联到关联的对象,相关的操作见后面,如果不指定,则为None
|
Cascade=ManyRelationCascadeEnum.All
|
|
Inverse
|
指定是否级联操作
|
Inverse =true|false
|
|
Schema
|
指定Schema的名字
|
Schema="ARDemo"
|
|
Table
|
指定持久化类所关联的数据库表名,如果表名与类名相同,可以省略
|
Table="posts"
|
|
ColumnKey
|
指定关联类的一个属性,这个属性将会和本外键相对应。
|
ColumnKey="post_blogid"
|
|
Where
|
指定一个附加SQL的Where子句
|
Where="IsPost = 0"
|
|
Lazy
|
指定是否延迟加载关联对象
|
Lazy=true|false
|
Cascade的类型值有如下几种
|
类型
|
说明
|
|
None
|
不进行级联操作
|
|
SaveUpdate
|
进行级联Save/Update操作
|
|
Delete
|
进行级联Delete操作
|
|
All
|
进行级联Save/Update/Delete操作
|
|
AllDeleteOrphan
|
进行级联Save/Update/Delete操作,并删除无相关父对象的子对象
|
在Post实体类中,我们需要定义一个Blog类型的属性,并且用到BlongsTo特性,即一个Post属于某一个Blog,代码如下:
[ActiveRecord("Posts")]

public class Post : ActiveRecordBase



{

//……

private Blog _blog;


[BelongsTo("blogid")]

public Blog Blog


{


get
{ return _blog; }


set
{ _blog = value; }

}

}
BelongsToAttribute说明
|
属性
|
说明
|
示例
|
|
Cascade
|
指定级联操作
|
Cascade=CascadeEnum.SaveUpdate
|
|
Column
|
列名,外键字段名
|
BelongsTo("blogid")
Column="blogid"
|
|
Insert
|
是否允许增加
|
Insert=true|false
|
|
NotNull
|
是否允许为空
|
NotNull =true|false
|
|
OuterJoin
|
是否允许外连接抓取
|
OuterJoin=OuterJoinEnum.True
|
|
Unique
|
是否唯一
|
Unique =true|false
|
|
Update
|
是否允许更新
|
Update =true|false
|
Cascade类型如下
|
选项
|
说明
|
|
None
|
默认值,不进行级联操作
|
|
All
|
进行级联Save/Update/Delete操作
|
|
SaveUpdate
|
进行级联Save/Update操作
|
|
Delete
|
进行级联Delete操作
|
OuterJoin选项有三个:Auto,True,False
最后完整的Blog实体类如下

/**//// <summary>

/// Blog 的摘要说明。

/// </summary>
[ActiveRecord("Blogs")]

public class Blog : ActiveRecordBase



{

private int _id;


private String _name;


private String _author;


private IList _posts;


[PrimaryKey(PrimaryKeyType.Native, "blog_id")]

public int Id


{


get
{ return _id; }


set
{ _id = value; }

}


[Property("blog_name")]

public String Name


{


get
{ return _name; }


set
{ _name = value; }

}


[Property("blog_author")]

public String Author


{


get
{ return _author; }


set
{ _author = value; }

}


[HasMany(typeof(Post), Table="posts", ColumnKey="post_blogid")]

public IList Posts


{


get
{ return _posts; }


set
{ _posts = value; }

}


public static void DeleteAll()


{

DeleteAll( typeof(Blog) );

}


public static Blog[] FindAll()


{

return (Blog[]) FindAll( typeof(Blog) );

}


public static Blog Find(int id)


{

return (Blog) FindByPrimaryKey( typeof(Blog), id );

}

}
完整的Post类如下


/**//// <summary>

/// Post 的摘要说明。

/// </summary>
[ActiveRecord("Posts")]

public class Post : ActiveRecordBase



{

private int _id;


private String _title;


private String _contents;


private String _category;


private DateTime _created;


private bool _published;


private Blog _blog;


public Post()


{

_created = DateTime.Now;

}


public Post(Blog blog, String title, String contents, String category) : this()


{

_blog = blog;

_title = title;

_contents = contents;

_category = category;

}


[PrimaryKey(PrimaryKeyType.Native,"post_id")]

public int Id


{


get
{ return _id; }


set
{ _id = value; }

}


[Property("post_title")]

public String Title


{


get
{ return _title; }


set
{ _title = value; }

}


[Property(Column="post_contents",ColumnType="StringClob")]

public String Contents


{


get
{ return _contents; }


set
{ _contents = value; }

}


[Property("post_categories")]

public String Category


{


get
{ return _category; }


set
{ _category = value; }

}


[BelongsTo("post_blogid")]

public Blog Blog


{


get
{ return _blog; }


set
{ _blog = value; }

}


[Property("post_created")]

public DateTime Created


{


get
{ return _created; }


set
{ _created = value; }

}


[Property("post_published")]

public bool Published


{


get
{ return _published; }


set
{ _published = value; }

}


public static void DeleteAll()


{

ActiveRecordBase.DeleteAll( typeof(Post) );

}


public static Post[] FindAll()


{

return (Post[]) ActiveRecordBase.FindAll( typeof(Post) );

}

}
三.构建配置信息
这里我采用上篇中将过的XML配置方式
<?xml version="1.0" encoding="utf-8" ?>

<activerecord>

<config>

<add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />

<add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2000Dialect" />

<add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider" />

<add key="hibernate.connection.connection_string" value="Data Source=.;Initial Catalog=test;Integrated Security=SSPI" />

</config>

</activerecord>
四.编写测试代码
1.级联增加:新增一个Blog,并同时添加相关的Post到数据表中
[Test]

public void TestCascadingSave()



{

//创建Blog对象

Blog blog = new Blog();

blog.Name="Terrylee's Tech Space";

blog.Author = "Terrylee";


//执行事务,持久化对象到数据库

using(TransactionScope tran = new TransactionScope())


{

try


{

blog.Create();


for(int i=1;i<11;i++)


{

//创建Post对象

Post post = new Post();

post.Title="This is my "+i.ToString()+" post";

post.Category="Castle";

post.Blog = blog;

post.Save();

}


tran.VoteCommit();

}

catch


{

tran.VoteRollBack();

}

}// The changes will be sent to the DB when the session is disposed here

}
2
.级联更新:
首先我们为一个已经存在的Blog增加多个Post
[Test]

public void TestCascadingUpdate()



{

//找到ID为5的Blog

Blog blog = Blog.Find(5);


//执行事务,持久化对象到数据库

using(TransactionScope tran = new TransactionScope())


{

try


{

for(int i=1;i<5;i++)


{

//创建Post对象

Post post = new Post();

post.Title="This is my "+i.ToString()+" post";

post.Category="Castle";


post.Save();


//注意这句

blog.Posts.Add(post);

}


blog.Update();


tran.VoteCommit();

}

catch


{

tran.VoteRollBack();

}

}

}
当然上面的更新代码也可以这样去写:
[Test]

public void TestCascadingUpdate()



{

//找到ID为5的Blog

Blog blog = Blog.Find(5);


//执行事务,持久化对象到数据库

using(TransactionScope tran = new TransactionScope())


{

try


{

for(int i=1;i<5;i++)


{

//创建Post对象

Post post = new Post();

post.Title="This is my "+i.ToString()+" post";

post.Category="Castle";


//在这儿指定它们的关联

post.Blog = blog;

post.Save();

}


tran.VoteCommit();

}

catch


{

tran.VoteRollBack();

}

}

}
但是如果我们去掉post.Save()这句话,就会发现Post并没有增加到库中:
[Test]

public void TestCascadingUpdate()



{

//找到ID为5的Blog

Blog blog = Blog.Find(5);


//执行事务,持久化对象到数据库

using(TransactionScope tran = new TransactionScope())


{

try


{

for(int i=1;i<5;i++)


{

//创建Post对象

Post post = new Post();

post.Title="This is my "+i.ToString()+" post";

post.Category="Castle";


//注释掉这句

//post.Save();


blog.Posts.Add(post);

}


blog.Update();


tran.VoteCommit();

}

catch


{

tran.VoteRollBack();

}

}

}
此时,必须修改我们的Blog类,设置级联操作为SaveUpdate,上面的代码才可以正常执行
// 


[HasMany(typeof(Post), Table="posts", ColumnKey="post_blogid",Cascade=ManyRelationCascadeEnum.SaveUpdate)]

public IList Posts



{


get
{ return _posts; }


set
{ _posts = value; }

}
下面再测试一个删除某一个Blog的某些Post后,再保存
[Test]

public void TestCascadingUpdateDel()



{

//找到ID为7的Blog

Blog blog = Blog.Find(7);

int expectedCount = blog.Posts.Count;


using(TransactionScope tran = new TransactionScope())


{

try


{

blog.Posts.RemoveAt(0);


blog.Update();


tran.VoteCommit();

}

catch


{

tran.VoteRollBack();

}

}


int actualCount = Blog.Find(7).Posts.Count;


Assert.AreEqual(expectedCount-1,actualCount);

}
上面这段代码测试可以通过,但是我们会发现表Posts中会有一些记录没有BlogId,修改Blog实体类重新设置级联操作,就可以正常删除了:
// 


[HasMany(typeof(Post), Table="posts", ColumnKey="post_blogid",Cascade=ManyRelationCascadeEnum.AllDeleteOrphan)]

public IList Posts



{


get
{ return _posts; }


set
{ _posts = value; }

}
3.级联删除
删除一个Blog对象后,对应的Post对象应该全部删除
[Test]

public void TestCascadingDelete()



{

//找到ID为7的Blog对象

Blog blog = Blog.Find(5);


using(TransactionScope tran = new TransactionScope())


{

try


{

blog.Delete();


tran.VoteCommit();

}

catch


{

tran.VoteRollBack();

}

}

}
同样要注意设置级联操作。
关于One-Many关联映射就介绍这么多了,至于Many-One关联同One-Many,只不过对HasMany和BlongsTo设置的位置不一样而已,在下一篇文章中我会介绍在ActiveRecord中实现Many-Many关联映射。
参考资料
Castle的官方网站http://www.castleproject.org
posted @ 2006-04-06 16:28
TerryLee 阅读(12250)
评论(62) 编辑 收藏 网摘 所属分类:
[11] 数据持久[12] 开源世界
发表评论
你的Post类写的有问题,没有办法测试通过。下面是我修改好的。
using System;
using Castle.ActiveRecord;
using CastleTest;
/**//// <summary>
/// Post 的摘要说明。
/// </summary>
[ActiveRecord("Posts")]
public class Post : ActiveRecordBase
{
private int _id;
private String _title;
private String _contents;
private String _category;
private DateTime _created;
private bool _published;
private Blog _blog;
public Post()
{
_created = DateTime.Now;
}
public Post(Blog blog, String title, String contents, String category) : this()
{
_blog = blog;
_title = title;
_contents = contents;
_category = category;
}
[PrimaryKey(PrimaryKeyType.Native,"post_id")]
public int Id
{
get { return _id; }
set { _id = value; }
}
[Property("post_title")]
public String Title
{
get { return _title; }
set { _title = value; }
}
[Property(Column="post_contents",ColumnType="StringClob")]
public String Contents
{
get { return _contents; }
set { _contents = value; }
}
[Property("post_categories")]
public String Category
{
get { return _category; }
set { _category = value; }
}
[BelongsTo("post_blogid")]
public Blog Blog
{
get { return _blog; }
set { _blog = value; }
}
[Property("post_created")]
public DateTime Created
{
get { return _created; }
set { _created = value; }
}
[Property("post_published")]
public bool Published
{
get { return _published; }
set { _published = value; }
}
public static void DeleteAll()
{
ActiveRecordBase.DeleteAll( typeof(Post) );
}
public static Post[] FindAll()
{
return (Post[]) ActiveRecordBase.FindAll( typeof(Post) );
}
}
#2楼[
楼主]2006-04-07 08:21 |
@CrazyWill
晕,贴错代码了:-)
谢谢,我找时间改过来
#3楼[
楼主]2006-04-09 08:48 |
终于更正过来了
公司里网络总是发不上去,耽误了大家这么长时间,实在不好意思:)
IConfigurationSource需要using哪个命名空间?
#5楼[
楼主]2006-05-14 08:41 |
@SK
命名空间:Castle.ActiveRecord.Framework
这里我在调试的时候碰到了几个问题,
一个就是ActiveRecordStarter.Initialize方法的第二个参数是一个param 的类型,所以所有type初始化都是在一个方法里完成了,我先前把他搞成两个了
还有就是Post类构造函数里设置时间初始值的那句好像是必须的,ActiveRecord好像不能自动将数据库时间类型的值设为null,它必须有一个初始值
这些只是我个人测试的结果,希望高手指点
请问我发现好像所有的主键都是自动增加,我在做试验的时候,发现如果不递增,就会报错,不能保存,修改。请问能否把表的主键改为不递增,能否用上面的方法实现。
@xu
可能是你的PrimaryKeyType设置问题
主键的生成方式介绍
Identity
对DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置标识字段提供支持,生成自增的整型
Sequence
序列,对DB2,MySQL, PostgreSQL, Oracle的内置标识字段提供支持,生成自增的整型。
HiLo
高低位,使用一个高/低位算法来高效的生成Int64, Int32 或者 Int16类型的标识符。
SeqHiLo
使用序列的高低位,使用一个高/低位算法来高效的生成Int64, Int32 或者 Int16类型的标识符,给定一个数据库序列(sequence)的名字。
UuidHex
用一个System.Guid和它的ToString(string format)方法生成字符串类型的标识符。
UuidString
用一个新的System.Guid产生一个byte[] ,把它转换成字符串。
Guid
用一个新的System.Guid 作为标识符。
GuidComb
用Jimmy Nilsso的一个算法产生一个新的System.Guid。
Native
根据底层数据库的能力选择 identity, sequence 或者 hilo中的一个。默认值。
Assigned
让应用程序在自己为对象分配一个标示符。
Foreign
使用另外一个相关联的对象的标识符。
#9楼[
楼主]2006-06-01 13:11 |
TerryLee
你好,又来麻烦你了:)
在“为一个已经存在的Blog增加多个Post”的代码中
为何数据库中只增加了for循环的最后一条记录呢?
#11楼[
楼主]2006-06-23 11:28 |
@一汐
把你的代码贴出来看一下吧,这样不好说是什么问题
@TerryLee
private void btnUpdate_Click(object sender, System.EventArgs e)
{
blog=Blog.Find(2);
using(TransactionScope tran = new TransactionScope())
{
try
{
blog.Name="Test";
for(int i=1;i<6;i++)
{
post.Title="this is new Title!";
post.Contents="Contents"+i;
post.Category="Castle";
post.Blog=blog;
post.Save();
}
tran.VoteCommit();
}
catch
{
tran.VoteRollBack();
}
}
}
这就是代码,是按你的示例代码写的
还有就是你看这句:blog=Blog.Find(2);
Find方法的参数只能是int的?
如果我想查找string岂不是很不方便?
#13楼[
楼主]2006-06-24 08:08 |
@一汐
这样看来没什么问题
这样吧,你把完整的代码发到我邮箱里面,我看一下
#14楼[
楼主]2006-06-26 16:36 |
@一汐
问题出在了你把创建Post对象的代码放在了for循环的外面,这样每次循环所做的其实是同一个Post对象,把代码修改成如下这样即可:
blog=Blog.Find(2);
using(TransactionScope tran = new TransactionScope())
{
try
{
blog.Name="Test";
blog.Author="TNSEB";
for(int i=1;i<5;i++)
{
// 注意这儿
Post post = new Post();
post.Title="this is new Title!";
post.Contents="Contents"+i;
post.Category="Castle";
post.Blog=blog;
post.Save();
}
blog.Save();
tran.VoteCommit();
}
catch
{
tran.VoteRollBack();
}
}
@TerryLee
呵呵,谢谢
我知道了,问题的关键还不是blog.Save()的问题
当然你说的也对,起初我是把这行代码放在了外边
但是问题还是存在,我把它挪到了里边
还是不行,就照你帮忙了
其实关键的原因在于// 注意这儿
Post post = new Post();
@TerryLee
呵呵,谢谢
我知道了,其实问题的关键还不是blog.Save()的问题
当然你说的也对,起初我是把这行代码放在了外边
但是问题还是存在,我把它挪到了里边
还是不行,就照你帮忙了
其实关键的原因在于
// 注意这儿
Post post = new Post();
这句
我是直接把post设为全局变量了:protected Blog blog = new Blog();
protected Post post = new Post();
应该每次使用时new一下
呵呵,多谢TerryLee百忙之中给与解答:)
#17楼[
楼主]2006-06-26 16:58 |
@一汐
嗯,问题就在那儿
所以我给你写了一句://注意这儿
呵呵
@TerryLee
post.Save()报错,而改成post.Create()就可以正常插入数据库了,这两个函数区别在于什么呢?
@TerryLee
不知道为何又可以了,怪事,原本直接复制你的代码
catch
{
tran.VoteRollBack();
}
当发现没有插入数据的时候进行调试,发现Save()直接被catch捕获,然后就改了Create()试试,通过。接着再改为Save();
并且改为
catch(Castle.ActiveRecord.Framework.ActiveRecordException sx)
{
System.Windows.Forms.MessageBox.Show(sx.Message);
tran.VoteRollBack();
}
居然正常了:(
#20楼[
楼主]2006-07-30 10:28 |
@microshot
这个不好说是什么原因,呵呵:-)
@TerryLee
能解释一下Create() 和Save()的区别吗?
#22楼[
楼主]2006-07-30 11:01 |
@microshot
在前面我说过,ActiveRecord底层封装的是NHibernate,而NHibernate中有Save(),Update(),SaveOrUpdate()几个方法,ActiveRecord是对这些方法作了一次封装。
Create()执行的操作:
----------------------------
session.Save(instance);
session.Flush();
Save()执行的操作:
-----------------------------
session.SaveOrUpdate(instance);
session.Flush();
@TerryLee
哦,明白,刚才刚看了一下castle的源代码:) 3x
#24楼[
楼主]2006-07-30 11:45 |
@microshot
不用客气:-)
@TerryLee
今天刚接触Castle,在你的讲解下觉得还不错,但是FindByPrimaryKey这个方法我怎么没有找到,我看了一下ActiveRecordBase里面没有这个方法,汗一下,我的Castle是从sourceforg下载过来的
#26楼[
楼主]2006-08-04 17:04 |
@jojoke
这个方法应该是2.0下的吧
@TerryLee
thanks
是Castle2.0下的? sorceforg不是最新的吗?
我这里是.net frameword 2.0 的,怎么System.Transaction也没有呢
奇怪
我的测试程序报这样一个错,麻烦TerryLee帮看下可能是什么原来造成的:
CastleTest2.NTest.UserTest.DeleteTest : Castle.ActiveRecord.Framework.ActiveRecordException : Could not perform DeleteAll for User
----> NHibernate.ObjectDeletedException : deleted object would be re-saved by cascade (remove deleted object from associations): 2, of class: CastleTest2.User
#29楼[
楼主]2006-08-14 08:38 |
@ditto
你看一下Cascade设置的对不对?
User类型这是这样设的
[BelongsTo(Column="Group_ID")]
public Group Group
....
Group类中我是这样设的
[HasMany(typeof(User), Table="Users", ColumnKey="Group_ID",Cascade=ManyRelationCascadeEnum.All)]
public System.Collections.IList Users
.....
这样有错吗?
Group类设成下面这个样子还是报一样的错:
[HasMany(typeof(User), Table="Users", ColumnKey="Group_ID",Cascade=ManyRelationCascadeEnum.AllDeleteOrphan)]
public System.Collections.IList Users
Group类设成
[HasMany(typeof(User), Table="Users", ColumnKey="Group_ID)]
public System.Collections.IList Users
的时候,不仅会报同样的错,而且不能执行了下代码:
Group grp=Group.Find(1);
User user2=new User();
user2.Name="XX";
user2.Sex="男";
user2.Age=28;
// user2.Save(); //这句注释掉了的,以测试级连更新
grp.Users=new ArrayList();
grp.Users.Add(user2);
grp.Update();
在one-many中,要通过主键删除many方的一个实体,该怎么办那.
直接使用"快速入门"中的方法,提示"无法更新标识列",如果使用这里提供的方法,还有找到Many方在One的位置.不过我想应该可以直接删除的.CS文件是系统生成的,没有作修改.
呵呵,找到不能删除的原因了,原来是用工具生成的代码有错,修改后就好了.
#34楼[
楼主]2006-08-23 14:01 |
@powerdel
不好意思,最近太忙了
一直没有顾得上回复!
把posts的外键设为不允许为空,级联删除时总是删不了,把外键改为允许为空就能删了,请问高手,这是怎么回事?
请问一下,XML配置方式 文件我已经生成好了。
我把它命名为Test.xml
我现在想用Nuit来测试,应该怎么来配置。我的程序怎么知道我的配置文件是Test.xml????????
先 谢谢
#37楼[
楼主]2006-10-14 11:48 |
public Post()
{
_created = DateTime.Now;
}
#39楼[
楼主]2006-10-24 13:01 |
@wzj
Post类里面有写啊
@powerdel
我也遇到无法更新标识列的问题,不知道是哪里生成的有问题,楼主没说清楚啊.
You have accessed an ActiveRecord class that wasn't properly initialized. The only explanation is that the call to ActiveRecordStarter.Initialize() didn't include 一对多.Blog class
============
嘛原因...
还有初始化的时候该怎么写呢?一个类的时候是这样.
ActiveRecordStarter.Initialize(source,typeof(Post));
两个类的时候是这样??
ActiveRecordStarter.Initialize(source,typeof(Post));
ActiveRecordStarter.Initialize(source,typeof(Blog));
#43楼[
楼主]2006-11-12 17:07 |
@paleyyang
ActiveRecordStarter.Initialize(source,typeof(Post),typeof(Blog));
请教像这种父子关系结构如何映射:
create table PropertyType (
TypeID int primary key not null,
ParentTypeID int foreign key references PropertyType(TypeID) null,
TypeName varchar(200) not null
)
#45楼[
楼主]2006-11-14 08:43 |
@liubo
典型的一对多啊,跟文章中的Blog和Post的关系一样,还是用HasMany和BelongsTo特性
可是报错啊,请再帮我看看:
[ActiveRecord("PropertyType")]
public class PropertyType:ActiveRecordBase
{
private int typeid;
private string typename;
private PropertyType parenttype;
[PrimaryKey(PrimaryKeyType.Identity,"typeid")]
public int TypeID
{
get {return typeid;}
set {typeid=value;}
}
[Property("typename")]
public string TypeName
{
get {return typename;}
set {typename=value;}
}
[HasMany(typeof(PropertyType),"typeid","propertytype")]
public PropertyType ParentType
{
get {return parenttype;}
set {parenttype=value;}
}
}
错误信息如下:Could not guess relation type for property PropertyType.ParentType .
#48楼[
楼主]2006-11-15 12:53 |
@liubo
:)
各位大侠:
我在测试 TestCascadingSave() 方法时有以下错误,代码都是在此页面Copy的 。求教了!
"You have accessed an ActiveRecord class that wasn't properly initialized. The only explanation is that the call to ActiveRecordStarter.Initialize() didn't include OneManyTest.Blog class"} System.Exception {Castle.ActiveRecord.Framework.ActiveRecordException}
抛出异常说:Hibernate.dialect的属性没有设置,可是我的配置文件里卖时设置了的啊!
@ni
我也遇到这个问题呢!还不知道是怎么回事呢!
You have accessed an ActiveRecord class that wasn't properly initialized. The only explanation is that the call to ActiveRecordStarter.Initialize() didn't include Blog class
报这个异常是什么原因呀?恳请大家帮帮忙呀!
@paleyyang
你好!我也出现了这个问题!请问你是怎么解决的呢!
SQL Server2000和SQL Server2005,
Hibernate.dialect的属性设置是不是一样的呀?
是不是都是NHibernate.Dialect.MsSql2000Dialect这个呀?
它和.NET是2.0还是1.0有没有关系呀?到现在还没有写一个成功的例子出,
郁闷呀!请各位帮帮忙了,感激不尽!
请教一个问题:
假如blog类和post类分别在程序集A和程序集B中,程序集B依赖于程序集A,但程序集A不能依赖于程序集B,即post知道有blog,但blog不知道有post,在此前提下如何实现post的O-R Mapping?
@orafan
ok了!
用JoinedKey代替BelongTo
one to one 怎么用的哦!可以用到一对多不哦!
我用这个代码有个示例public class Blog : ActiveRecordBase
{ private int _id;
private String _name;
private String _author;
private IList _posts;//这个地方有错,ILIST少一个参数,但你就是这么写的为么不对呢!???
[PrimaryKey(PrimaryKeyType.Native, "blog_id")]
public int Id
{
get { return _id; }
set { _id = value; }
}
[Property("blog_name")]
public String Name
{
get { return _name; }
set { _name = value; }
}
[Property("blog_author")]
public String Author
{
get { return _author; }
set { _author = value; }
}
[HasMany(typeof(Post), Table="posts", ColumnKey="post_blogid")]
public IList Posts//这个地方也是,ILIST少一个参数,但你就是这么写的为么不对呢!???
{
get { return _posts; }
set { _posts = value; }
}
麻烦再说清楚一点
这里的两张表在数据库里建了外键关系,我尝试把这个外键关系删掉,然后运行测试,发现post_blogid里还是填入了blog_id的值,我就奇怪了,castle就怎么确定我的所想要的一对多指的是blog_id<=post_blogid,在以上的代码中无论是HasMary还是BelongsTo都只指明了post_blogid,castle是默认将post_blogid与主键对应吗?在一些其它的场合,如果我们的需求怪异一点话,我希望将post_blogid与Blog的其它字段建立一对多的关系又怎么实现呢?
刚才有个网友说他们公司一般不会使用HasMary或BelongsTo特性到Model中,表间关系都是自己控制,您觉得这样做可行吗?