Castle从实体类生成数据库表
文/sonce 出处/博客园
前段时间刚接触了NHibernate,它让我这个懒写SQL语句的人偷懒了许多,就是闲编写实体类,映射文件麻烦点。后来就用CodeSmith代码生成工具来生成实体类,和映射文件。哎,弄的我更懒了。不过还是要我建立数据库表也麻烦,还不如直接写个实体类,然后来生成数据库表,这样可能我能够更闲点。恩,最近接触了Castle,看了TerryLee的Castle文章,Castle不像Nhibernate那样要通过映射文件来映射实体类的,而是采用Attribute。看到其中一篇由实体类生成数据库表的文章。
1:建立实体类
Blogs.cs

Code
using Castle.ActiveRecord;
[ActiveRecord("Blogs")]
public class Blogs : ActiveRecordBase<Blog>
{
private int _blogId;
private string _blogName;
private string _blogAuthor;
private System.Collections.IList _posts;
private System.Collections.IList _community;
[PrimaryKey(PrimaryKeyType.Native, "blog_id")]
public int BlogId
{
get
{
return this._blogId;
}
set
{
this._blogId = value;
}
}
[Property(Column = "blog_name", SqlType = "varchar(50)")]
public string BlogName
{
get
{
return this._blogName;
}
set
{
this._blogName = value;
}
}
[Property(Column = "blog_author", SqlType = "varchar(50)")]
public string BlogAuthor
{
get
{
return this._blogAuthor;
}
set
{
this._blogAuthor = value;
}
}
[HasAndBelongsToMany(typeof(Community), Table = "Blog_Community", ColumnRef = "community_Id", ColumnKey = "blog_Id")]
public System.Collections.IList Communitys
{
get { return _community; }
set { _community = value; }
}
}
Communityies.cs

Code
using Castle.ActiveRecord;
[ActiveRecord("Communities")]
public class Community : ActiveRecordBase<Community>
{
private int _communityId;
private string _communityName;
private string _communityIntro;
private System.Collections.IList _blog;
[PrimaryKey(PrimaryKeyType.Native, "community_Id")]
public int CommunityId
{
get
{
return this._communityId;
}
set
{
this._communityId = value;
}
}
[Property(Column="community_Name")]
public string CommunityName
{
get
{
return this._communityName;
}
set
{
this._communityName = value;
}
}
[Property(Column="community_Intro")]
public string CommunityIntro
{
get
{
return this._communityIntro;
}
set
{
this._communityIntro = value;
}
}
[HasAndBelongsToMany(typeof(Blog),Table="Blog_Community",ColumnRef="blog_id",ColumnKey="community_id")]
public System.Collections.IList Blogs
{
get { return _blog; }
set { _blog = value; }
}
}
Castle配置就不多说了。这里的两个类用HasAndBelongsToMany特性来实现Many-Many的关联。在Global.asax的Application_Start里面做初始化操作。

Code
void Application_Start(object sender, EventArgs e)
{
Castle.ActiveRecord.Framework.IConfigurationSource source = System.Configuration.ConfigurationManager.GetSection("activerecord") as Castle.ActiveRecord.Framework.IConfigurationSource;
Castle.ActiveRecord.ActiveRecordStarter.Initialize(typeof(Blogs).Assembly, source);
}
随便点。建立一个aspx页面,拉个Button控件,

Code
protected void Button1_Click(object sender, EventArgs e)
{
ActiveRecordStarter.CreateSchema();
}
然后运行。报错了,“各表中的列名必须唯一。在表 'Blog_Community' 中多次指定了列名 'blog_Id'。 ”。那我们看看生成的SQL代码。改下代码,让Castle把sql保存到一个文件里面。
ActiveRecordStarter.GenerateCreationScripts(@"d:\a.sql");
打开这个文件。

Code
alter table Blog_Community drop constraint FKE1062E1B2A8806
alter table Blog_Community drop constraint FKE1062E1B4A8806
alter table Blog_Community drop constraint FKE1062E1FE5CF140
alter table Blog_Community drop constraint FKE1062E1A96E5DE0
if exists (select * from dbo.sysobjects where id = object_id(N'Blogs') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table Blogs
if exists (select * from dbo.sysobjects where id = object_id(N'Blog_Community') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table Blog_Community
if exists (select * from dbo.sysobjects where id = object_id(N'Communities') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table Communities
create table Blogs (
blog_id INT IDENTITY NOT NULL,
blog_name varchar(50) null,
blog_author varchar(50) null,
primary key (blog_id)
)
create table Blog_Community (
community_id INT not null,
blog_id INT not null,
blog_Id INT not null,
community_Id INT not null
)
create table Communities (
community_Id INT IDENTITY NOT NULL,
community_Name NVARCHAR(255) null,
community_Intro NVARCHAR(255) null,
primary key (community_Id)
)
alter table Blog_Community add constraint FKE1062E1B2A8806 foreign key (blog_Id) references Blogs
alter table Blog_Community add constraint FKE1062E1B4A8806 foreign key (blog_id) references Blogs
alter table Blog_Community add constraint FKE1062E1FE5CF140 foreign key (community_Id) references Communities
alter table Blog_Community add constraint FKE1062E1A96E5DE0 foreign key (community_id) references Communities
首先删除了表中的关联,然后判断数据库中是否有这些表,如果有的话就删除,然后在创建表,然后添加约束。
在TerryLee的文章中写道"生成数据库表时只有当该表不存在时ActiveRecord才会生成,否则表如果存在ActiveRecord不会做任何事情,也不会报任何错误。"。但看它生成的SQL语句并非如此。TerryLee在Castle ActiveRecord学习实践(10):深度分析Schema Pitfals 有补充说明。
回头看看刚刚的那个错误,查找到创建Blog_Community表的语句,

Code
create table Blog_Community (
community_id INT not null,
blog_id INT not null,
blog_Id INT not null,
community_Id INT not null
)
是这里的问题。看来是Many-many关联引起的。
于是去掉其中一个类里面的HasAndBelongsToMany特性。然后生成。可以了。不知道高手们有否其他的方法呢?
看了下Castle的源代码,额,原来是封装了NHibernate.Tool.hbm2ddl.SchemaExport里面的方法。
| 感谢原创者的辛勤劳动,希望对您有所帮助,转载请注明原出处。 |