Nhibernate中的父子映射

Nhibernate中的父子映射,nhibernate,orm,nhibernate-mapping,Nhibernate,Orm,Nhibernate Mapping,数据库中有两个表:Order和OrderLine。OrderLine有一个外键指向Order.Id的not可为空列(OrderId) 在代码中,我有两个类:Order和OrderLine。订单有一个订单行集合,但订单行没有对订单的引用 如果不引入从订单行到订单的引用或在订单行内维护一个带有订单id的私有字段(如中所示),则无法映射此关系,这是正确的吗 先谢谢你 下面的代码显示了实体和映射 namespace NhibernateMappingTests { [TestClass]

数据库中有两个表:Order和OrderLine。OrderLine有一个外键指向Order.Id的not可为空列(OrderId)

在代码中,我有两个类:Order和OrderLine。订单有一个订单行集合,但订单行没有对订单的引用

如果不引入从订单行到订单的引用或在订单行内维护一个带有订单id的私有字段(如中所示),则无法映射此关系,这是正确的吗

先谢谢你

下面的代码显示了实体和映射

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
{
[测试类]
公共类映射示例2
{
[测试方法]
公共void InsertTest()
{
使用(var session=NHibernateHelper.OpenSession())
{
使用(var transaction=session.BeginTransaction())
{
订单=新订单();
AddOrderLine(neworderline());
会话。保存(命令);
Commit();
}
}
}
}
公共阶级秩序
{
公共秩序()
{
OrderLines=新列表();
}
公共int Id{get;set;}
公共IList命令行{get;set;}
公共无效AddOrderLine(OrderLine OrderLine)
{
订单行。添加(订单行);
}
}
公共类命令行
{
公共int Id{get;set;}
}
公共类OrderMap:ClassMap
{
公共秩序地图()
{
不是。懒汉();
Id(x=>x.Id).GeneratedBy.Identity();
HasMany(x=>x.OrderLines)
.AsBag()
.Cascade.All()
.KeyColumn(“OrderId”);
}
}
公共类OrderLineMap:ClassMap
{
公共OrderLineMap()
{
不是。懒汉();
Id(x=>x.Id).GeneratedBy.Identity();
}
}
公共类NHibernateHelper
{
私人静态ISessionFactory_sessionFactory;
私有静态ISessionFactory会话工厂
{
得到
{
if(_sessionFactory==null)
初始化SessionFactory();
返回工厂;
}
}
私有静态void InitializeSessionFactory()
{
_sessionFactory=fluntly.Configure()
.Database(MsSqlConfiguration.MsSql2008.ConnectionString(@“数据源=(本地)\db01;初始目录=MyDatabase;持久安全信息=false;数据包大小=4096;集成安全性=sspi;”)。ShowSql()
.Mappings(m=>m.FluentMappings.AddFromAssemblyOf())
//.ExposeConfiguration(cfg=>newschemaexport(cfg).Create(true,true))
.BuildSessionFactory();
}
公共静态会话OpenSession()
{
返回SessionFactory.OpenSession();
}
}
}
它会导致以下异常:

测试方法NhibernateMappingTests.MappingExample2.InsertTest引发异常:
NHibernate.Exceptions.GenericADOException:无法插入:[NhibernateMappingTests.OrderLine][SQL:插入到[OrderLine]默认值中;选择SCOPE_IDENTITY()]-->System.Data.SqlClient.SqlException:无法将值NULL插入到“OrderId”列、表“MyDatabase.dbo.OrderLine”中;列不允许空值。插入失败。

您实际上只能在一侧映射关系,这不重要

尽管在这种情况下将执行update语句。要修复该异常,只需将映射更改为

HasMany(x => x.OrderLines) 
  .AsBag() 
  .Cascade.AllDeleteOrphan() // or .All
   .KeyColumn("OrderId")
   .Not.KeyNullable();

当然,如果您不想拥有双向映射/导航属性,只需不映射即可。它应该只在一侧使用mapped。但是NHibernate似乎更喜欢使用OrderLine.OrderId=NULL进行插入,然后更新OrderLine.OrderId=xx。但是OrderLine.OrderId不可为Null,因此我遇到Foreingkey冲突。发布您的映射和实体代码,我可能会为您提供帮助。我已经用您请求的实体和映射更新了问题。您的代码实际上对我很好。我还将该列手动更改为不可为null,但它仍然可以工作。而且它不会产生任何无效的sql插入。。。当您遇到问题时,是否确实保存了订单?如果你只保存订单行,这就行不通了。现在我不能100%确定我是否正确理解了你的问题。