如何使用NHibernate创建一对一的关系,其中另一侧可能是NULL?例如,我有一个与图像实体有关系的横幅实体,如下所示:
<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>
因此,对于横幅实体,图像可以为空。我创建了一个没有图像的横幅实体,没有任何问题。在数据库中,我有
--------------
ID | ImageId
--------------
1 | NULL
之后,我正在尝试创建第二个没有图像的横幅实例,并收到以下错误:
NHibernate.Exceptions.GenericADOException: 无法插入: [域.实体.横幅][SQL:插入到横幅 (ImageId( 值 (?(; 选择 SCOPE_IDENTITY((] ---> System.Data.SqlClient.SqlException: 违反唯一键约束"UQ_横幅_7516F70DE6141471"。 无法在对象 'dbo 中插入重复键。横幅'。重复键 值为 ((。
我想,发生这种情况是因为我对横幅和图像实体之间的一对多关系有独特的约束,并且多个横幅实例在 ImageId 字段中不能有多个 NULL 值。问题:我将如何在 NHinerbate 中实现 1 到零的一个关系?
谢谢!
解决方案是从Banner
表中移动ImageId
。并将其放在Image
桌上。
这样,每当我们有真实的(非空(图像时,我们就可以让:
- 通过图像(
- 从图像侧
many-to-one
,并从横幅侧收集图像one-to-many
(引用横幅(BannerId
(或 - 使用真实的
one-to-one
关系:ImageId
是不受约束的,由拥有的班纳BannerId
产生。
这是文档 5.1.11 的示例。 一对一,调整为横幅和图像
现在我们必须确保 BANNER 中相关行的主键 和图像表相等。我们使用特殊的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"/>