Castle从实体类生成数据库表

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

 

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
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里面做初始化操作。

 

     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控件,

 

     protected   void  Button1_Click( object  sender, EventArgs e)
    
{
        ActiveRecordStarter.CreateSchema();
    }


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

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表的语句,

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里面的方法。文章很菜,谢谢观赏。

你可能感兴趣的:(cast)