[导入]Castle ActiveRecord学习记录

  这两天看了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以及许多无私奉献的前辈们!

aggbug.aspx?PostID=1211
文章来源: 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值