nhibernate映射:具有cascade=”的集合;“全部删除孤立项”;不再被引用

nhibernate映射:具有cascade=”的集合;“全部删除孤立项”;不再被引用,nhibernate,fluent-nhibernate,nhibernate-mapping,Nhibernate,Fluent Nhibernate,Nhibernate Mapping,我在流畅的映射方面遇到了一些问题。我有一个实体,它有一个子实体集合,例如Event和EventItems 如果将集合的级联映射设置为AllDeleteOrphan,则在将新实体保存到数据库时会出现以下错误: NHibernate.HibernateException:拥有实体实例Core.Event.EventItems不再引用cascade=“all delete orphan”的集合 如果我将级联设置为所有,它可以正常工作吗?下面是我的类和映射文件: public class EventM

我在流畅的映射方面遇到了一些问题。我有一个实体,它有一个子实体集合,例如Event和EventItems

如果将集合的级联映射设置为AllDeleteOrphan,则在将新实体保存到数据库时会出现以下错误: NHibernate.HibernateException:拥有实体实例Core.Event.EventItems不再引用cascade=“all delete orphan”的集合

如果我将级联设置为所有,它可以正常工作吗?下面是我的类和映射文件:

 public class EventMap : ClassMap<Event>
{
    public EventMap()
    {
        Id(x => x.Id, "Id")
            .UnsavedValue("00000000-0000-0000-0000-000000000000")
            .GeneratedBy.GuidComb();

        Map(x => x.Name);
        HasMany(x => x.EventItems)
            .Inverse()
            .KeyColumn("EventId")
            .AsBag()
            .Cascade.AllDeleteOrphan();
    }
}

  public class EventItemMap : SubclassMap<EventItem>
{
    public EventItemMap()
    {
         Id(x => x.Id, "Id")
            .UnsavedValue("00000000-0000-0000-0000-000000000000")
            .GeneratedBy.GuidComb();
        References(x => x.Event, "EventId");
    }
}



public class Event : EntityBase
{
    private IList<EventItem> _EventItems;

    protected Event()
    {
        InitMembers();
    }

    public Event(string name)
        : this()
    {
        Name = name;
    }

    private void InitMembers()
    {
        _EventItems = new List<EventItem>();
    }

    public virtual EventItem CreateEventItem(string name)
    {
        EventItem eventItem = new EventItem(this, name);
        _EventItems.Add(eventItem);
        return eventItem;
    }

    public virtual string Name { get; private set; }
    public virtual IList<EventItem> EventItems
    {
        get
        {
            return _EventItems.ToList<EventItem>().AsReadOnly();
        }
        protected set
        {
            _EventItems = value;
        }
    }
}

    public class EventItem : EntityBase
{
    protected EventItem()
    {
    }

    public EventItem(Event @event, string name):base(name)
    {
        Event = @event;
    }

    public virtual Event Event { get; private set; }
}
公共类事件映射:类映射
{
公共事件地图()
{
Id(x=>x.Id,“Id”)
.UnsavedValue(“00000000-0000-0000-0000-000000000000”)
.GeneratedBy.GuidComb();
Map(x=>x.Name);
HasMany(x=>x.EventItems)
.Inverse()
.KeyColumn(“事件ID”)
.AsBag()
.Cascade.AllDeleteOrphan();
}
}
公共类EventItemMap:子类映射
{
public EventItemMap()
{
Id(x=>x.Id,“Id”)
.UnsavedValue(“00000000-0000-0000-0000-000000000000”)
.GeneratedBy.GuidComb();
引用(x=>x.Event,“EventId”);
}
}
公共类事件:EntityBase
{
私人IList_事件项目;
受保护事件()
{
InitMembers();
}
公共事件(字符串名称)
:此()
{
名称=名称;
}
私有成员()
{
_EventItems=新列表();
}
公共虚拟事件项CreateEventItem(字符串名称)
{
EventItem EventItem=新的EventItem(此,名称);
_添加(eventItem);
返回事件项;
}
公共虚拟字符串名称{get;private set;}
公共虚拟IList事件项
{
得到
{
返回_EventItems.ToList().AsReadOnly();
}
保护集
{
_EventItems=值;
}
}
}
公共类EventItem:EntityBase
{
受保护的EventItem()
{
}
public EventItem(Event@Event,字符串名):base(name)
{
Event=@Event;
}
公共虚拟事件事件{get;private set;}
}
这里很难办。非常感谢任何提示

Chev

检查此SO帖子:

对公认答案的评论也有类似的问题


您可能希望尝试删除
事件项的
AsReadOnly
,以检查这是否是原因。

您需要使用访问策略映射事件项,以便NHibernate访问私有成员而不是属性。出现此错误是因为当列表复制到
\u EventItems.ToList()
中的新列表时,集合引用发生了更改。试试这个:

public class EventMap : ClassMap<Event>
{
    public EventMap()
    {
        Id(x => x.Id, "Id")
            .UnsavedValue("00000000-0000-0000-0000-000000000000")
            .GeneratedBy.GuidComb();

        Map(x => x.Name);
        HasMany(x => x.EventItems)
            .Access.PascalCaseField(Prefix.Underscore)
            .Inverse()
            .KeyColumn("EventId")
            .AsBag()
            .Cascade.AllDeleteOrphan();
        }
    }
}
公共类事件映射:类映射
{
公共事件地图()
{
Id(x=>x.Id,“Id”)
.UnsavedValue(“00000000-0000-0000-0000-000000000000”)
.GeneratedBy.GuidComb();
Map(x=>x.Name);
HasMany(x=>x.EventItems)
.Access.PascalCaseField(前缀.下划线)
.Inverse()
.KeyColumn(“事件ID”)
.AsBag()
.Cascade.AllDeleteOrphan();
}
}
}

我认为公认的答案不是一种优雅的方法。这里可能存在的问题是Chev正在从数据库读取事件,然后将新的
EventItem
列表分配给
EventItems
属性。当您忽略以前的子列表并分配新的子列表时,NHibernate会引发此异常

你需要做的是

如果要丢弃旧的
事件项
,请执行以下操作:

events.EventItems.Clear();
events.EventItems.Add(new EventItem { blah blah });

为什么要使用子类映射?那是打字错误吗?杰米-我可以告诉你我是多么感激你!10年后,我和塞缪尔G一样感激你:谢谢你的回答——没有解决这个问题。看看杰米的答案。这就解决了问题。谢谢你的回复。