NHibernate:试图保存包含集合的实体时出现问题

NHibernate:试图保存包含集合的实体时出现问题,nhibernate,orm,persistence,fluent,Nhibernate,Orm,Persistence,Fluent,我需要一些帮助 我刚从NHibernate开始,我使用Fluent进行映射。直到今天,一切似乎都很顺利。 故事是这样的: 我的数据库中有两个表:存储和工作日 第一个表包含有关商店的信息,WorkDay表包含有关商店开门的一周天数和开始/结束时间的信息。 Store包含在WorkDay表中引用的GuidStoreIDPK列。 因此,我有一个存储的映射文件,其中我有一个与工作日表有许多关联,以及存储对应的POCO。 现在,当我填充所有必要的数据并尝试将其持久化到数据库时,我得到一个异常,告诉我插入表

我需要一些帮助

我刚从NHibernate开始,我使用Fluent进行映射。直到今天,一切似乎都很顺利。 故事是这样的:

我的数据库中有两个表:存储工作日 第一个表包含有关商店的信息,WorkDay表包含有关商店开门的一周天数和开始/结束时间的信息。 Store包含在WorkDay表中引用的GuidStoreIDPK列。 因此,我有一个存储的映射文件,其中我有一个工作日表有许多关联,以及存储对应的POCO。 现在,当我填充所有必要的数据并尝试将其持久化到数据库时,我得到一个异常,告诉我插入表WorkDay失败,因为StoreID具有null值,并且表约束不允许该列为null(当然,这是预期的行为)

我理解这个异常的原因,但我不知道如何解决它。 插入失败的原因是插入时生成了StoreID,但在尚未生成StoreID时,[b]WorkDay[/b]collection首先被保存

那么,如何强制NHibernate生成该ID以将其传递给依赖表呢?还是有其他解决办法

谢谢大家!

这是StoreMap的代码

public class StoreMap : ClassMap<Store> {
    public StoreMap() {
        Id(x => x.StoreID)
            .GeneratedBy.GuidComb();
        Map(x => x.City);
        Map(x => x.Description);
        Map(x => x.Email);
        Map(x => x.Fax);
        Map(x => x.ImageData).CustomType("BinaryBlob");
        Map(x => x.ImageMimeType);
        Map(x => x.Name);
        Map(x => x.Phone);
        Map(x => x.Street);
        Map(x => x.Zip);

        HasMany(x => x.WorkDays)
            .Inverse().KeyColumn("StoreID").ForeignKeyCascadeOnDelete()
            .Cascade.All();
    }
}
公共类存储映射:类映射{
公共存储地图(){
Id(x=>x.StoreID)
.GeneratedBy.GuidComb();
地图(x=>x.City);
映射(x=>x.Description);
Map(x=>x.Email);
地图(x=>x.Fax);
Map(x=>x.ImageData).CustomType(“二进制blob”);
Map(x=>x.ImageMimeType);
Map(x=>x.Name);
地图(x=>x.Phone);
地图(x=>x.Street);
Map(x=>x.Zip);
有很多(x=>x个工作日)
.Inverse().KeyColumn(“StoreID”).ForeignKeyCascadeOnDelete()
.Cascade.All();
}
}
这是工作日地图

public class WorkDayMap : ClassMap<WorkDay>{
    public WorkDayMap() {
        Id(x => x.WorkDayID)
            .GeneratedBy.Identity();
        Map(x => x.TimeOpen);
        Map(x => x.TimeClose);
        References(x => x.Store).Column("StoreID");
        References(x => x.Day).Column("DayID");
    }
}
公共类WorkDayMap:ClassMap{
公共工作日地图(){
Id(x=>x.WorkDayID)
.GeneratedBy.Identity();
Map(x=>x.TimeOpen);
Map(x=>x.TimeClose);
引用(x=>x.Store).Column(“StoreID”);
参考(x=>x.Day).列(“DayID”);
}
}

NHibernate不应首先插入
WorkDay
,因此您的代码中一定有错误。确保执行以下所有操作:

  • 将所有
    WorkDay
    对象添加到
    WorkDays
    集合中
  • 将所有
    WorkDay
    对象上的
    Store
    属性设置为父对象
  • 调用
    session.Save()
    用于
    Store
    ,但不用于
    WorkDay
    对象

  • 编辑:您还应该注意,
    ForeignKeyCascadeOnDelete()
    在运行时不会更改任何内容。这只是hbm2ddl工具的一个属性。如果希望NHibernate删除删除的条目,请使用
    Cascade.AllDeleteOrphan()

    它可能会在存储之前插入工作日,因为第一个工作日具有
    标识
    生成器。这将强制NH执行INSERT语句以生成ID。
    guid.comb
    在内存中生成,NH不需要数据库

    NH尝试在最新可能的时间点访问数据库,以避免不必要的更新并利用批处理。Workday在您调用会话时插入。Save、Store在下次刷新会话时插入(如提交时)

    您不应该使用标识生成器(除非您被迫使用它)。无论如何,这对性能是不利的



    如果它仍然不起作用,您可能需要删除外键上的NOTNULL约束。NH不能每次都解决它。有一些智能算法也能够处理递归引用。但有时它会将外键设置为null,并在以后更新它,即使有解决方案可以避免它。

    如果删除
    .Inverse()
    ,会出现什么错误?我尝试了,但没有帮助我会投票支持你,但我没有足够的声誉!我需要guid,但我将更改表,使其具有单独的ID列,并将guid放在另一列中。我看看它是否有效。非常感谢。我改变了栏目,但没用。删除NN约束使插入成为可能,但ID随后没有更新。guid正常,但标识不好!使用guid.comb或hilo。它以前是guid.comb。我猜你在我提供的代码中没有看到。实际上你是对的!我确信NHibernate在初始化和赋值方面发挥了所有的作用,我认为调用
    store.WorkDays.Add(…)
    就足够了,新的WorkDay对象将自动从调用对象获取
    StoreID
    引用!现在我把
    store.WorkDays.Add(newworkday{store=store})
    放进去,它就可以正常工作了。