HasMany不是空外键

时间:2010-11-26 06:35:20

标签: fluent-nhibernate

我有两个类(示例中简化):

public class Data
{
    public int Id {get; set;}
    public string Value { get; set; }
}
public class DataContainer
{
    public int Id {get; set;}
    public IList<Data> DataPoints { get; set; }
}

基本上,DataContainer类有一组数据(和其他未显示的属性)。 Data类不了解DataContainer,但它不能存在于一个之外。我为此使用 HasMany 关系。

我像这样映射DataContainer:

Id(x => x.Id);
HasMany<Data>(x => x.DataPoints)
    .Not.KeyNullable()
    .Cascade.All();

生成的SQL数据如下所示:

create table [Data] (
   [Id] INT IDENTITY NOT NULL,
   [DataContainer] INT null,
   primary key ([Id])
)
alter table [Data] 
    add constraint FK173EC9226585807B 
    foreign key ([DataContainer]) 
    references [DataContainer]

问题是我不想 [DataContainer] INT null ,而是我希望它不允许空值

[DataContainer] INT not null

我认为 .Not.KeyNullable()会这样做,但它似乎不起作用。

感谢。

2 个答案:

答案 0 :(得分:2)

我有完全相同的映射和相同的结果但是看看Fluent生成的hbm.xml看起来它可以在这里做到。集合映射看起来像这样(注意“key”元素上的“not-null”属性):

<bag cascade="all" name="Items" mutable="true">
  <key foreign-key="FK_MyEntity2_MyEntity1" not-null="true">
    <column name="MyEntity1_Id" />
  </key>
  <one-to-many class="MyNs.MyEntity2, MyAssembly, Version=0.4.700.0, Culture=neutral, PublicKeyToken=null" />
</bag>

因此我认为这是一个NHibernate问题,而不是一个Fluent问题。以下内容摘自最新的NHibernate参考(3.0.0,但我很确定2.1.2中也是如此)

  

非常重要注意:如果&lt; key&gt;关联的列声明为NOT NULL,NHibernate在创建或更新关联时可能会导致约束违规。要防止出现此问题,必须使用标记为inverse =“true”的多值结束(集合或包)的双向关联。请参阅本章后面的双向关联讨论。

所以我的猜测是NHibernate在为这个映射生成DDL时忽略了“not-null”属性,并且解决方案是使关联双向如上所述(肯定有效,但可能不适合您的场景)或者直播使用NULL列。

答案 1 :(得分:0)

我有相同的映射并通过使关系双向(如Yhrn所建议)解决它,然后通过将Constrained()。ForeignKey()声明添加到映射来强制执行外键约束:

在Data类中:

 this.HasOne(x => x.DataContainer).Cascade.All().Constrained().ForeignKey();

生成的SQL中的列仍然可以为空,但添加了外键:

ALTER TABLE [dbo].[Data]  WITH CHECK ADD  CONSTRAINT [FK_DataToDataContainer] FOREIGN KEY([Id])
REFERENCES [dbo].[DataContainer] ([Id])
GO

ALTER TABLE [dbo].[Data] CHECK CONSTRAINT [FK_DataToDataContainer]
GO