3

如何使用 NHibernate 创建一对一关系,而另一端可能是 NULL?例如,我有一个 Banner 实体,它与 Image 实体有如下关系:

<class name="Banner" table="Banner">
    <id name="Id" type="Int64" unsaved-value="0">
        <generator class="native" />
    </id>

    <many-to-one name="Image" unique="true" column="ImageId" not-null="false"/>

    <!-- check: In the example this property was without inverse attribute -->
    <set name ="BannerSlideSet" fetch="subselect" inverse="true">
        <key column="Banner_ID" foreign-key="FK_Banner_BannerSlide" not-null="false" />
        <one-to-many class="BannerSlide"/>
    </set>
</class>

因此,对于 Banner 实体,Image 可以为空。我创建了一个没有图像的横幅实体,没有任何问题。在数据库中我有

--------------
ID  | ImageId
--------------
 1  | NULL

之后,我尝试创建第二个没有 Image 的 Banner 实例,并得到以下错误:

NHibernate.Exceptions.GenericADOException: 无法插入:[Domain.Entities.Banner] [SQL: INSERT INTO Banner (ImageId) VALUES (?); 选择 SCOPE_IDENTITY()] ---> System.Data.SqlClient.SqlException:违反 UNIQUE KEY 约束“UQ_ Banner _7516F70DE6141471”。无法在对象“dbo.Banner”中插入重复键。重复键值为 ()。

我想,这是因为我对横幅和图像实体之间的一对多关系有独特的约束,并且几个 Banner 实例在 ImageId 字段中不能有多个 NULL 值。问题:我将如何在 NHinerbate 中实现一对空的关系?

谢谢!

4

1 回答 1

3

解决方案是ImageId Banner表中移出。并将其放在Image桌子上。

这样,只要我们有真实(非空)图像,我们就可以让:

  1. 按图像引用横幅( BannerId) (从图像一侧,从横幅一侧收集图像)或many-to-oneone-to-many
  2. 使用真实one-to-one关系:ImageId是唯一受约束的,由拥有横幅的BannerId.

这是文档5.1.11中的示例。一对一,调整为Banner和Image

现在我们必须确保 BANNER 和 IMAGE 表中相关行的主键相等。我们使用一种特殊的 NHibernate 标识符生成策略,称为 foreign:

图像映射:

<class name="Image" table="[Image]">
    <id name="Id" column="[ImageId]">
        <generator class="foreign">
            <param name="property">Banner</param>
        </generator>
    </id>
    ...
    <one-to-one name="Banner" class="Banner" constrained="true"/>
</class>

横幅:

 <one-to-one name="Image" class="Image"/>
于 2013-09-29T05:36:07.960 回答