HasMany映射具有不可为空的键列

时间:2013-01-21 17:09:08

标签: nhibernate fluent-nhibernate

我正在尝试使用不可为空的键列实现HasMany映射。

我的映射如下所示:

public void Override(AutoMapping<DataExportTable> mapping)
{
    mapping.Table("data_export_tables");
    mapping.Id(x => x.Id).Column("data_export_tables_id")
           .GeneratedBy.Sequence("SQ_DATA_EXPORT_TABLES_ID");
    mapping.HasMany(x => x.Columns)
           .KeyColumn("table_id")
           .Not.KeyNullable()
           .Not.KeyUpdate()
           .Cascade.AllDeleteOrphan();
}

保存实体的代码如下所示:

var table = new DataExportTable("table_name");
table.Columns.Add(new DataExportColumn("column_name"));
session.Save(table);
transaction.Commit();

这会引发异常:

  

NHibernate.Exceptions.GenericADOException:无法执行批处理命令。[SQL:SQL不可用] ---&gt; Oracle.DataAccess.Client.Orac   leException:ORA-01400:无法插入NULL(“MYSCHEMA”。“DATA_EXPORT_COLUMNS”。“TABLE_ID”)

现在,我读了很多关于这个主题的帖子,普遍接受的解决方案似乎是将参考文档双向化,即向Table添加DataExportColumn属性并设置它。登记/> 另一个“黑客”是使外键列可以为空。 那不是我想要的。我希望NHibernate直接在INSERT语句中插入ID 根据日志文件,NHibernate在执行INSERT语句时肯定知道ID:

  

NHibernate:从双重中选择SQ_DATA_EXPORT_TABLES_ID.nextval   NHibernate:批处理命令:
  命令0:INSERT INTO data_export_tables(NAME,data_export_tables_id)VALUES(:p0,:p1);: p0 ='table_name'[Type:String(0)] ,: p1 = 93 [Type:Int32(0)]

     

NHibernate:批量命令:
  命令0:INSERT INTO data_export_columns(NAME,data_export_columns_id)VALUES(:p0,:p1);:p0 =   'column_name'[类型:字符串(0)] ,: p1 = 1228 [类型:Int32(0)]

正如您所看到的,NHibernate只是省略了table_id列,虽然ID是众所周知的 - NHibernate将它作为参数传递给第一个插入语句...

2 个答案:

答案 0 :(得分:2)

如此接近,您需要设置Not.Inverse(),如this answer所示。

mapping.HasMany(x => x.Columns)
       .KeyColumn("table_id")
       .Not.Inverse()
       .Not.KeyNullable()
       .Not.KeyUpdate()
       .Cascade.AllDeleteOrphan();

我不认为将双向关系变为黑客,通常需要进行查询。

答案 1 :(得分:2)

您没有提到您正在使用的NHibernate版本 - 但我会注意到,根据this jira issue,这似乎已在版本3.2.0中得到修复。

如果您坚持使用另一个版本的NHibernate,我建议将关系设置为双向,因为在我看来,这是使用可空的FK的更好选择。