Nhibernate 中的父子映射
Posted
技术标签:
【中文标题】Nhibernate 中的父子映射【英文标题】:Parent and child mapping in Nhibernate 【发布时间】:2013-10-05 15:28:37 【问题描述】:我在数据库中有两个表:Order 和 OrderLine。 OrderLine 有一个不可可为空的列 (OrderId),外键指向 Order.Id。
在代码中我有两个类:Order 和 OrderLine。 Order 有一个 OrderLines 集合,但 OrderLine 没有对 Order 的引用。
如果不引入从 OrderLine 到 Order 的引用,或者在 OrderLine 中维护一个带有订单 ID 的私有字段,如this blog post (variation 3) 所示,您不能映射此关系是正确的吗?
提前致谢……
以下代码显示了实体和映射
namespace NhibernateMappingTests
[TestClass]
public class MappingExample2
[TestMethod]
public void InsertTest()
using (var session = NHibernateHelper.OpenSession())
using (var transaction = session.BeginTransaction())
Order order = new Order();
order.AddOrderLine(new OrderLine());
session.Save(order);
transaction.Commit();
public class Order
public Order()
OrderLines = new List<OrderLine>();
public int Id get; set;
public IList<OrderLine> OrderLines get; set;
public void AddOrderLine(OrderLine orderLine)
OrderLines.Add(orderLine);
public class OrderLine
public int Id get; set;
public class OrderMap : ClassMap<Order>
public OrderMap()
Not.LazyLoad();
Id(x => x.Id).GeneratedBy.Identity();
HasMany(x => x.OrderLines)
.AsBag()
.Cascade.All()
.KeyColumn("OrderId");
public class OrderLineMap : ClassMap<OrderLine>
public OrderLineMap()
Not.LazyLoad();
Id(x => x.Id).GeneratedBy.Identity();
public class NHibernateHelper
private static ISessionFactory _sessionFactory;
private static ISessionFactory SessionFactory
get
if (_sessionFactory == null)
InitializeSessionFactory();
return _sessionFactory;
private static void InitializeSessionFactory()
_sessionFactory = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008.ConnectionString(@"data source=(local)\db01;initial catalog=MyDatabase;persist security info=false;packet size=4096;integrated security=sspi;").ShowSql())
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<TimeSeries>())
//.ExposeConfiguration(cfg => new SchemaExport(cfg).Create(true, true))
.BuildSessionFactory();
public static ISession OpenSession()
return SessionFactory.OpenSession();
它会导致以下异常:
测试方法 NhibernateMappingTests.MappingExample2.InsertTest 抛出异常: NHibernate.Exceptions.GenericADOException:无法插入:[NhibernateMappingTests.OrderLine] [SQL:INSERT INTO [OrderLine] 默认值;选择 SCOPE_IDENTITY()] ---> System.Data.SqlClient.SqlException:无法将值 NULL 插入到列“OrderId”、表“MyDatabase.dbo.OrderLine”中;列不允许空值。插入失败。
【问题讨论】:
【参考方案1】:您实际上只能在一侧映射关系,这无关紧要。
虽然在这种情况下会执行更新语句。要修复异常,您只需将映射更改为
HasMany(x => x.OrderLines)
.AsBag()
.Cascade.AllDeleteOrphan() // or .All
.KeyColumn("OrderId")
.Not.KeyNullable();
【讨论】:
好吧,如果你不想拥有双向映射/导航属性,就不要映射它。它应该只在一侧使用映射。 但似乎 NHibernate 更喜欢使用 OrderLine.OrderId = NULL 进行插入,然后再更新 OrderLine.OrderId = xx。但是 OrderLine.OrderId not 可以为空,因此我得到了 Foreingkey 违规。 发布您的映射和实体代码,我或许可以为您提供帮助。 我已经用您请求的实体和映射更新了问题。 您的代码实际上对我来说很好。我还手动将列更改为不可为空,但它仍然有效。并且它不会产生任何无效的 sql 插入...您确定在遇到问题时保存了订单吗?如果您只保存 OrderLine,这是行不通的。现在我不能 100% 确定我是否正确理解了您的问题 .以上是关于Nhibernate 中的父子映射的主要内容,如果未能解决你的问题,请参考以下文章
防止 NHibernate 将 Returning 子句添加到生成的插入语句中
如何在 Fluent NHibernate 中将一对一关系映射为复合键的一部分