NHibernate:被删除的对象会被级联重新保存.替换对象并删除旧对象 [英] NHibernate: deleted object would be re-saved by cascade. Replace object and remove old one

查看:14
本文介绍了NHibernate:被删除的对象会被级联重新保存.替换对象并删除旧对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试替换 ProgramItem 上的 TimeBlock 对象,然后删除旧的 TimeBlock 对象.是删除部分给我带来了问题.我在删除旧的 TimeBlock 对象时遇到了一些相对"简单的 nHibernate 问题.

I'm trying to replace at TimeBlock object on a ProgramItem and then delete the old TimeBlock object. It's the delete part that gives me problems. I have some 'relative' simple nHibernate problems deleting the old TimeBlock object.

例外:
删除的对象将通过级联重新保存(从关联中删除删除的对象)[*.Model.TimeBlock#15]
15 是 oldTimeBlock 的 ID

我通常在解决此类问题时没有遇到任何问题,因为我几乎尝试了以下任何用法:

I usually don't have any problems solving this kind of issue by I just tried almost any usages of:

oldTimeBlock.ProgramItems = new List<ProgramItem>();
programItem.TimeBlock = null;

以及以任意顺序保存和删除块并使用 Inverse() 更改映射.
我需要一些新鲜的眼光 - 我怎样才能做到这一点?

and the save and delete blocks in any order and changing the mapping with Inverse().
I need some fresh eyes - how could I make this work?

代码:

public class TimeBlock
{
    public virtual int Id { get; set; }
    public virtual IList<ProgramItem> ProgramItems { get; set; }
    ...
}

public class TimeBlockMap : ClassMap<TimeBlock>
{
    public TimeBlockMap()
    {
        Id(x => x.Id);
        HasMany(x => x.ProgramItems).Cascade.SaveUpdate(); // Have tested with Inverse() but seemed to make no difference
    }
}


public class ProgramItem : ImageModel, IIdentifiable
{
    public virtual int Id { get; set; }
    public virtual TimeBlock TimeBlock { get; set; }
    ...
}

public class ProgramItemMap : ClassMap<ProgramItem>
{
    public ProgramItemMap()
    {
        Id(x => x.Id);
        References(x => x.TimeBlock);
    }
}


//Delete old TimeBlock and set new TimeBlock to ProgramItem

var oldTimeBlock = programItem.TimeBlock;

using (var tx = session.BeginTransaction())
{
    oldTimeBlock.ProgramItems = new List<ProgramItem>();
    programItem.TimeBlock = null;
    //session.Save(programItem);
    //session.Save(oldTimeBlock);
    session.Delete(oldTimeBlock);
    tx.Commit(); // location of the exception. If i move the delete oldTimeBlock part below the save programItem part it will still fail in the delete oldTimeBlock part.
}

using (var tx = session.BeginTransaction())
{
    programItem.TimeBlock = timeBlock;
    session.Save(programItem);
    tx.Commit();
}

推荐答案

我试着在这里详细解释发生了什么

I tried explain what is happening in detail here

我想说,重点在这里:ProgramItem 被其他一些集合引用.该集合也被加载到会话中.

I would say, that the point is here: the ProgramItem is referenced by some other collection. And that collection was also loaded into the session.

最好的起点是 - 无论在哪里使用 ProgramItem(集合项、引用),都将映射更改为 Cascade.None().然后尝试执行您的删除代码.那会起作用...当然,因为现在级联到位...无法触发该异常.

The best place where to start is - wherever is ProgramItem used (collection item, reference) change the mapping to Cascade.None(). Then try to execute your deletion code. That will work... surely, becuase now cascading in place... no way how to trigger that exception.

下一步 - 开始逐个级联.确保你知道什么是允许的,然后你就会知道哪个引用、集合正在重新保存你的对象.

Next - start cascading by pieces. Be sure you know what is allowed, and then you will know which reference, collection is re-saving your object.

我自己的经验/方法是 - 如果您从一个地方删除该项目,如果有级联,则也从其他地方明确删除它.这可能具有挑战性,但是...

My own experience/approach is - if you delete the item from one place, explicitly delete it from others as well, if there is cascade. It could be challenging, but...

这篇关于NHibernate:被删除的对象会被级联重新保存.替换对象并删除旧对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆