最近在项目中使用Castle ActiveRecord,在使用HasMany定义的关联时出现了无法级联删除的问题。
我在项目中定义了两个实体类FeedEntry和FeedEntryLink如下:
[ActiveRecord(Table = "FeedEntries")]
public class FeedEntry : ActiveRecordBase<FeedEntry>
{
[PrimaryKey(PrimaryKeyType.GuidComb)]
public Guid Id { get; set; }
[Property]
public string Title { get; set; }
[Property]
public string Content { get; set; }
[Property]
public DateTime LastUpdatedTime { get; set; }
[HasMany(Cascade = ManyRelationCascadeEnum.AllDeleteOrphan)]
public IList<FeedEntryLink> FeedEntryLinks { get; set; }
}
[ActiveRecord(Table = "FeedEntryLinks")]
public class FeedEntryLink : ActiveRecordBase<FeedEntryLink>
{
[PrimaryKey(PrimaryKeyType.GuidComb)]
public Guid Id { get; set; }
[Property]
public string RelationshipType { get; set; }
[Property]
public string MediaType { get; set; }
[Property]
public string Uri { get; set; }
[BelongsTo("FeedEntryId")]
public FeedEntry FeedEntry { get; set; }
}
其中FeedEntry中有一个集合属性FeedEntryLinks定义了它到类FeedEntryLink的一对多关联。而在FeedEntryLink中则有一个FeedEntry属性关联到父类FeedEntry。
在我的应用中需要删除所有的FeedEntry,因此我使用了下面的语句:
FeedEntry.DeleteAll();
看似非常简单的一个语句,执行的时候却报出了下面的错误:
System.Data.SqlClient.SqlException: Cannot insert the value NULL into column 'FeedEntryId', table 'calendar-test.dbo.FeedEntryLinks'; column does not allow nulls. UPDATE fails.
The statement has been terminated.
明明是想删除,可是却试图往外键列中插入NULL,这是为什么呢?
不甘心的我打开sql server profiler,在执行语句FeedEntry.DeleteAll()时监控了生成的sql语句,果然发现出现了如下奇怪的sql:
exec sp_executesql N'UPDATE FeedEntryLinks SET FeedEntryId = null WHERE FeedEntryId = @p0',N'@p0 uniqueidentifier',@p0='7303FFBF-3E3C-4CB3-8ED5-9EF9016BFE0F'
看来真的是在试图插入空值!
经过查验多发资料,发现原来是Inverse惹的祸!
根据nhibernate的官方说明,Inverse属性指定了双向关联中的所有者,它的默认值为false。因此,在我的问题中,默认由关联的“子”方也就是FeedEntryLink来维护关联。
当我需要删除父表中的记录时,维护关联的子表方为了解除关联,就会试图把其所引用的父表设为空,然后再试图删除父表的记录,因此就有了上述生成的奇怪sql语句。
那么如果我把Inverse设置成true呢?比如说我把上面的HasMany改成:
[HasMany(Cascade = ManyRelationCascadeEnum.AllDeleteOrphan, Inverse = true)]
public IList<FeedEntryLink> FeedEntryLinks { get; set; }
这个时候再执行删除操作,会生成怎样的sql呢?再次使用sql server profiler我抓到了如下sql:
exec sp_executesql N'DELETE FROM FeedEntryLinks WHERE Id = @p0',N'@p0 uniqueidentifier',@p0='65EBBCF5-FBA7-4206-8C06-9EF90162559A'
这确实是我期望的删除命令。由于这时候由“父”方负责维护关联,因此当它试图删除父记录时,需要保证所有依赖关联的子记录都已被删除,所以就会执行上面的sql命令。
最后总结一下:Inverse定义了关联的维护方。
(1)当由子方来维护关联时,删除父记录时子记录会试图将关联断开,也就是置空。
(2)当由父方来维护关联时,删除父记录时会试图级联删除子记录。
分享到:
相关推荐
CASTLE ACTIVERECORD学习实践(1):快速入门指南 CASTLE ACTIVERECORD学习实践(2):构建配置信息 CASTLE ACTIVERECORD学习实践(3):映射基础 CASTLE ACTIVERECORD学习实践(4):实现ONE-MANY关系的映射 CASTLE...
Castle.ActiveRecord官方已经停止更新了,官方最高支持到NHibernate 3.1.0.4000,这个版本还有不少问题(例如:[NH-2213] - CLONE -Wrong parameters order in IQuery with SetParameterList and Filter)。...
Castle ActiveRecord快速入门指南,ActiveRecord帮助文档
castle ActiveRecord 源代码 nhibernate封装 C#
Castle.ActiveRecord 的资料很多,但是WINFORM...这个例子使用的是ACCESS数据库,从单表,一对多,多对多,数据绑定,HQL查询等多方面解译了Castle.ActiveRecord的基本用法,并付上了Castle.ActiveRecord的API及教程。
Castle ActiveRecord CHM帮助文档 最全的学习资料,经典例子,入门必备,技术人员随身携带的备查工具书。
包含ActiveRecord、Castle API、NHibernate.Documentation、NHibernate.Reference 等关于Castle ActiveRecord的帮助文档
Castle ActiveRecord 2.0
ActiveRecord 手册Castle ActiveRecord学习 快速入门指南
Castle.ActiveRecord For .NET FrameWork 2.0 如果你想使用Castle.ActiveRecord,但又不想使用.NET Framework 3.0/3.5/4.0或更高版本,那么这个就是你所需要的,For .NET FrameWork 2.0,我整理了好久,自己从官方...
简单Castle.ActiveRecord.Generator的例子。 包括添加,修改,删除,察看的基本功能。 包含建库脚本。
C# Castle.ActiveRecord CS源码示例教程.zip
Wpf使用Castle.ActiveRecord的示例,Castle针对.NET平台下的一个非常优秀的开源项目,其对数据访问层封装的非常不错,使开发者能省下大量数据访问的工作量,此示例比较基础,适合入门的朋友参考下,所需要的控件已在...
基于Castle ActiveRecord实现数据访问层的PetShop ASP.NET源码。
找这个资源的人都知道这是干什么的,就不多说什么了,
Castle.ActiveRecord 3.0.0+NHibernate 3.0.0.4000+SQLite+NVelocity 服务器控件 组合案例 VS环境:VS2010 数据访问框架: Castle.ActiveRecord 3.0.0 + NHibernate3.0.0.4000 当前测试数据库:SQLite (要改变...
Apress Pro ActiveRecord Databases with Ruby and Rails <br>Active Record has primarily been covered as a subsection, or maybe as a chapter or two, within a larger scoped book generally about the ...
Castle ActiveRecord 连接各种数据引擎的配置文件归纳
将ActiveRecord中的NHibernate升级到3.3.0GA,排除编译的bug问题,保留ActiveRecord的完整功能,【Castle.ActiveRecord 升级NHibernate到3.4.0GA】的功能不完整!
ActiveRecord简单实例_activerecord.zip