【问题标题】:Unidirectional one-to-many NHibernate mapping failing when using FluentNHibernate PersistenceSpecification使用 FluentNHibernate PersistenceSpecification 时单向一对多 NHibernate 映射失败
【发布时间】:2013-03-13 16:22:26
【问题描述】:

我有一个域模型,其中 Order 有许多 LineItems。当我创建一个新的Order(带有新的LineItems)并使用PersistenceSpecification 来测试映射时,NHibernate 会抛出一个 PropertyValueException:

var order = new Order() { LineItems = new List<LineItem>() };
order.LineItems.Add(new LineItem());
new PersistenceSpecification<Order>(session)
    .CheckList(o => o.LineItems, order.LineItems) // PropertyValueException
    .VerifyTheMappings();

NHibernate.PropertyValueException:非空属性引用空值或瞬态值 LineItem._Order.LineItemsBackref

领域模型

public class Order {
    public virtual Guid Id { get; set; }
    public virtual ICollection<LineItem> LineItems { get; set; }
    [...]
}
public class LineItem {
    public virtual Guid Id { get; set; }
    [...]
}

LineItem 本身并不有趣,如果没有Order,它们永远不会出现,因此关系是单向的。

Fluent 映射/架构

// OrderMap.cs
Id(x => x.Id).GeneratedBy.GuidComb();
HasMany(x => x.LineItems)
  .Not.Inverse()
  .Not.KeyNullable()
  .Not.KeyUpdate()
  .Cascade.AllDeleteOrphan();

// LineItemMap.cs
Id(x => x.Id).GeneratedBy.GuidComb();

// Schema
CREATE TABLE Orders    ( Id uniqueidentifier NOT NULL, /* ... */ )
CREATE TABLE LineItems ( Id uniqueidentifier NOT NULL, 
                         OrderId uniqueidentifier NOT NULL, /* ... */ )

LineItems 表中的外键列不可为空,因此基于the information in this question,我指定了Not.KeyNullable()Not.Inverse(),以防止NHibernate 尝试插入带有NULL 的LineItem Id

我正在使用 NHibernate 3.3.2.400 和 FluentNHibernate 1.3.0.733(来自 NuGet 的当前最新版本)。

【问题讨论】:

  • 请您提供数据库表的架构和一些导致异常的代码测试代码? Order 和 LineItem 属性也需要 Virtual 关键字。
  • 根据您提供的信息,我编写了一个运行良好的测试用例,为订单和订单项执行正确的插入。您可以在goo.gl/RwF08 下载测试 VS 2012 项目。
  • @penfold 呃,真尴尬。我想我已经过多地剥离了我的例子。感谢您花时间做我自己应该做的事情。 :)
  • 没问题,我花了很短的时间 ;) 如果您可以更新问题以便可以重现异常,我会再看一下。

标签: nhibernate fluent-nhibernate nhibernate-mapping fluent-nhibernate-mapping


【解决方案1】:

这是因为the CheckList() method tries to save each item in the list 只要您调用它。此时,父实体尚未保存——这不会发生until you call VerifyTheMappings()

由于关系是单向的,因此子实体 (LineItem) 不能持久化,除非它是父实体 (Order) 的一部分,并引发异常。 (GitHub issue)

除了“不要费心测试列表映射”之外,我还没有解决方案。

【讨论】:

  • 感谢您发布此问题并报告问题。在找到它之前,我以为我很密集...您在此期间找到了解决方案吗?如果不是,您认为我在本期提出的解决方案如何?
猜你喜欢
  • 1970-01-01
  • 2012-04-14
  • 1970-01-01
  • 2012-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-29
  • 1970-01-01
相关资源
最近更新 更多