[导入]Castle ActiveRecord学习记录

原文链接:http://www.cnblogs.com/debug1/archive/2006/05/14/413758.html

  这两天看了TerryleeActiveRecord学习实践系列,使我对Castle的ActiveRecord有了一个初步的认识。今天先把实践中遇到的一些小问题作个记录,便于日后总结、修正。

  最初遇到的一个问题就是:在做Many-Many关系映射,用实体类生成数据表的时候出现异常,如下:
************** Exception Text **************
Castle.ActiveRecord.Framework.ActiveRecordException: Could not create the schema
---> NHibernate.HibernateException: Column names in each table must be unique. Column name 'blog_id' in table 'Blog_Community' is specified more than once.
---> System.Data.SqlClient.SqlException: Column names in each table must be unique. Column name 'blog_id' in table 'Blog_Community' is specified more than once.
...

实体类设计如下:


[ActiveRecord("Blogs")]
public class Blog : ActiveRecordBase<Blog>
{
private int _id;
private String _name;
private String _author;
[PrimaryKey(PrimaryKeyType.Native, "blog_id")]
public int Id
{
get { return _id; }
set { _id = value; }
}
[Property("blog_name", NotNull = true)]
public String Name
{
get { return _name; }
set { _name = value; }
}
[Property("blog_author", NotNull = true)]
public String Author
{
get { return _author; }
set { _author = value; }
}
private IList _posts;
[HasMany(typeof(Post), Table = "Posts", ColumnKey = "post_blogid")]
public IList Posts
{
get { return _posts; }
set { _posts = value; }
}
private IList _community;
[HasAndBelongsToMany(typeof(Community), Table = "Blog_Community", ColumnRef = "community_id", ColumnKey = "blog_id ")]
public IList Communities
{
get { return _community; }
set { _community = value; }
}
}
[ActiveRecord("Posts")]
public class Post : ActiveRecordBase<Post>
{
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", NotNull = true)]
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; }
}
}
[ActiveRecord("Communities")]
public class Community : ActiveRecordBase<Community>
{
private int _id;
private String _name;
private String _intro;
[PrimaryKey(PrimaryKeyType.Native, "community_id")]
public int Id
{
get { return _id; }
set { _id = value; }
}
[Property("community_name", NotNull = true)]
public String Name
{
get { return _name; }
set { _name = value; }
}
[Property("community_intro")]
public String Intro
{
get { return _intro; }
set { _intro = value; }
}
private IList _blog;
[HasAndBelongsToMany(typeof(Blog), Table = "Blog_Community", ColumnRef = "blog_id", ColumnKey = "community_id")]
public IList Blogs
{
get { return _blog; }
set { _blog = value; }
}
}

  当时以为是Many–Many的映射在正向生成数据表时,由于成对出现的HasAndBelongsToMany属性,导致重复创建Blog_Community表的列(blog_id,community_id)而导致以上错误。虽然这个问题应该是不会出现的,但实在没找出具体原因,也只能暂且认为是AR本身的问题了 -_-!  于是乎就跳过它,接着搞。
  在做过另一些实验后,回过头来突然发现Many–Many的映射在正向生成数据表时又执行成功了.... 一阵莫名其妙&*%^*%^$  仔细地对照了前后的代码,发现原因出在空格符上(实体类代码中红色背景部分)。 

在Sql里不区分大小写,一般的空格符也会被忽略掉,例如这个小例子:
create table T_tmp (t_id int, t_name varchar(25))
alter table T_tmp add  t_id int  --报错 (这里的 t_id前有个空格)
错误信息:
Msg 2705, Level 16, State 4, Line 2
Column names in each table must be unique. Column name 'id' in table 'T_tmp' is specified more than once.

create table [ T_tmp](t_id int)   --成功创建了表 T_tmp
select * from  T_tmp
select * from [ T_tmp]

回到C#里,C#是区分大小写的,而且"blog_id "(右边有空格)和"blog_id"是不同的。所以在生成数据表时,应该就会去创建"blog_id "和"blog_id"两个字段,而到数据库中则认为这两个列名是相同的,异常就这样产生了。同理大小写的不同也会造成以上错误。
看来学习还是严谨点好,尤其是在一些细节上。又一次教训!

 

  另外发现AR里ActiveRecordBase挺好用的,它已经为我们重写了基础的静态方法,如Find(),TryFind(),DeleteAll(),FindAll()。这样不仅减少了我们的代码量,也保证了类型安全。要提一下的是,其中Find()在没有找到符合的结果时会抛出"Castle.ActiveRecord.NotFoundException"类型的异常。如果不希望抛出异常则可以使用TryFind(),它只返回null值。

 

留下几个待进一步实践学习的东西
1. 关于延时加载 lazy
2. 有继承关系的类怎样较好地转化为AR的实体类

 

最后,感谢Terrylee以及许多无私奉献的前辈们!

[导入]Castle ActiveRecord学习记录
文章来源:http://www.agilelabs.cn/blogs/%e8%8c%83%e4%bf%8a/archive/2006/05/14/1211.aspx

转载于:https://www.cnblogs.com/debug1/archive/2006/05/14/413758.html

上一篇:关于sql连接语句中的Integrated Security=SSPI相关解释


下一篇:关于sql连接语句中的Integrated Security=SSPI