C# 在fluent nHibernate中一对一模拟Cascade.AllDeleteOrphan
我有一个与子表具有可选的1:1关系的父表(父表可以不包含子表而存在,反之亦然)。父表的自动生成主键用作子表的主键/外键 多亏了几位好的推荐人(和),我才得以建立起一种1:1的工作关系。我可以创建一个包含或不包含子级的父级,更新一个或两个,并删除父级级联以删除子级,如预期的那样 但是,我想以某种方式“模拟”我的C# 在fluent nHibernate中一对一模拟Cascade.AllDeleteOrphan,c#,nhibernate,fluent-nhibernate,fluent-nhibernate-mapping,C#,Nhibernate,Fluent Nhibernate,Fluent Nhibernate Mapping,我有一个与子表具有可选的1:1关系的父表(父表可以不包含子表而存在,反之亦然)。父表的自动生成主键用作子表的主键/外键 多亏了几位好的推荐人(和),我才得以建立起一种1:1的工作关系。我可以创建一个包含或不包含子级的父级,更新一个或两个,并删除父级级联以删除子级,如预期的那样 但是,我想以某种方式“模拟”我的HasOne映射结构中HasMany映射的Cascade.AllDeleteOrphan()选项,这样,如果删除了关系的子端,则在保存父对象时将删除子表中的对应行。照目前的情况,如果我试图手
HasOne
映射结构中HasMany
映射的Cascade.AllDeleteOrphan()
选项,这样,如果删除了关系的子端,则在保存父对象时将删除子表中的对应行。照目前的情况,如果我试图手动删除子对象,我会得到一条“已删除的对象将通过cascade重新保存”错误消息,这是可以理解的
...
Parent parent = parentService.GetById(uniqueID);
if (parent.Child != null)
{
childService.Remove(parent.Child); // this gives the above error
parent.Child = null;
}
是否有人找到了一个好方法来做到这一点,同时仍然只使用HasOne
映射?我想做的是仍然是一对一的关系,还是仅仅使用一对多,依靠数据库约束和业务逻辑来防止多个孩子
简化代码:
// Parent class
public partial class Parent
{
public int pkParentID { get; set; }
public Child child { get; set; }
public Parent() { }
}
// Child class
public partial class Child
{
public int pkParentID {get; set; }
public Parent parent { get; set; }
public Child() { }
public Child(Parent parent) { this.parent = parent; }
}
// Parent mapping
public class ParentMap : ClassMap<Parent>
{
public ParentMap()
{
Table(@"Parent");
LazyLoad();
Id(x => x.pkParentID)
.Column("pkProjectID")
.Not.Nullable()
.GeneratedBy.Identity();
HasOne<Child>(x => x.Child)
.PropertyRef(r => r.Parent)
.Cascade.All();
}
}
// Child map
public class ChildMap :ClassMap<Child>
{
public ChildMap()
{
Table(@"Child");
LazyLoad();
Id(x => x.pkParentID, "pkParentID")
.GeneratedBy.Foreign("Parent");
HasOne<Parent>(x => x.Parent)
.Constrained()
.ForeignKey()
.Cascade.None();
}
}
// Ideally, the code snippet below would remove the row from the Child table
Parent parent = service.GetById(uniqueID);
if (parent.Child != null)
parent.Child = null;
service.SaveOrUpdate(parent);
// Just in case, here's my repository code
public virtual void SaveOrUpdate(T entity)
{
ISession _session = NHibernateSessionProvider.GetSession();
if (!_session.Transaction.IsActive)
{
using (ITransaction transaction = _session.BeginTransaction())
{
try
{
_session.SaveOrUpdate(entity);
transaction.Commit();
}
catch
{
transaction.Rollback();
}
}
}
}
NHibernate中未实现级联设置all delete orphan,请参阅。在对该问题的评论中有一个pull请求,因此它可能会出现在未来的版本中
目前,您可以执行以下操作:
Parent parent = service.GetById(uniqueID);
parent.Child = null;
service.Delete(parent.Child); // probably needs to occur in a different repository
// commit transaction or flush session, there's no need to call SaveOrUpdate
杰米-谢谢你的回复。那个确切的代码实际上不起作用,因为我会将NULL传递给service.Delete()
。但我想我知道你的意图,我也尝试过类似的方法(如你所提到的,使用特定于儿童的存储库)。由于我在父对象上有Cascade.All()
,因此尝试通过子存储库删除子对象时会出现“已删除的对象将通过Cascade重新保存”错误消息。