如何在另一侧可能为NULL的情况下使用NHibernate创建一对一关系?
例如,我有一个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可以为null。
我创建了一个没有图像的横幅实体,没有任何问题。
在数据库中我有

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


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


  NHibernate.Exceptions.GenericADOException:无法插入:
  [Domain.Entities.Banner] [SQL:将横幅广告插入(ImageId)值(?);
  选择SCOPE_IDENTITY()] ---> System.Data.SqlClient.SqlException:
  违反UNIQUE KEY约束'UQ_Banner_7516F70DE6141471'。
  无法在对象“ dbo.Banner”中插入重复键。重复键
  值是()。


我猜是因为我对横幅和图像实体之间的一对多关系有唯一的约束,并且几个横幅实例在ImageId字段中不能有多个NULL值,所以发生了。问题:如何在NHinerbate中实现一对一的关系?

谢谢!

最佳答案

解决方案是将ImageIdBanner表中移出。并将其放在Image表中。

这样,只要我们有真实的(不是null的)图像,我们就可以:


通过图像引用横幅(BannerId)(从图像一侧引用many-to-one,从横幅一侧引用图像的one-to-many)或
使用真实的one-to-one关系:ImageId是不受约束的,由拥有者Banner的BannerId生成。


这是文档5.1.11. one-to-one的示例,已调整为Banner和Image


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


图像映射:

<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"/>

关于c# - nhibernate一对一映射和not-null =“false”吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19073568/

10-11 15:52