使用 Nhibernate hbm 映射在具有相同 ID 的多个表中插入记录

Insert records in multiple tables with same ID with Nhibernate hbm mapping

我有两个 table,Table 1 有一个标识列(AttachmentID)和其他字段,Table 2 有一个 AttachmentID 列,它是 [=29= 的 FK ] 和 PK(不是标识列),因此 Table1.AttachmentID = Table2.AttachmentID,对于 Table1 的所有记录,记录可能会或可能不会出现在 Table2 中。

当我使用 Nhibernate 实体 类 保存记录时,table 1 和 Table2 中的记录以正确的关系正确插入,但它也在执行 SCOPE_IDENTITY() 在插入 table 2 之后,因为 table 2 没有任何标识列,所以 SCOPE_IDENTITY 给出 null 并且由于这个完整的操作失败。

正在执行以下插入查询

exec sp_executesql N'INSERT INTO Table1 (FileName, GroupID, RelativeStorageLocation, FileSize, FileStatus, StorageTypeID, DocumentId, AccessKey, AttachmentSource, FileThumbnailID) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9); select SCOPE_IDENTITY()',N'@p0 nvarchar(4000),@p1 int,@p2 nvarchar(4000),@p3 bigint,@p4 int,@p5 int,@p6 int,@p7 nvarchar(4000),@p8 int,@p9 int',@p0=N'IMG_20180108_145645.jpg',@p1=52122,@p2=NULL,@p3=0,@p4=3,@p5=0,@p6=0,@p7=NULL,@p8=5,@p9=NULL    
exec sp_executesql N'INSERT INTO Table2 (DateTaken, ImageSource, ImageLocation, AttachmentID) VALUES (@p0, @p1, @p2, @p3); select SCOPE_IDENTITY()',N'@p0 datetime,@p1 nvarchar(4000),@p2 nvarchar(4000),@p3 int',@p0='2018-01-08 14:56:45',@p1=N'Xiaomi Redmi Note 4',@p2=N'Murzuq District, Libya',@p3=13045  

以下是 Nhibernate hbm 文件

Table 1(通用附件)

<id name="_id" column="AttachmentID" access="field">
  <generator class="identity"/>
</id>

<property name="FileName" update="false"/>
<property name="GroupID"/>
<many-to-one name="GenericAttachmentGroup" class="GenericAttachmentGroup" column="GroupID" fetch="select" cascade="none" not-null="false" update="false" insert="false"/>
<property name="RelativeStorageLocation"/>
<property name="FileSize"/>
<property name="FileStatus" />
<property name="StorageTypeID" column="StorageTypeID" />
<property name="DocumentId" not-null="false"/>
<property name="AccessKey" not-null="false"/>
<property name="AttachmentSource" column="AttachmentSource" />
<many-to-one name="Thumbnail" class="FileInformation" column="FileThumbnailID" fetch="select" cascade="save-update" not-null="false" not-found="ignore"/>
<one-to-one lazy="proxy" name="Metadata" class="GenericAttachmentMatadataDetails" fetch="select" cascade="save-update" outer-join="true"  property-ref="GenericAttachment" />

Table 2(GenericAttachmentMatadataDetails)

<id name="_id" column="AttachmentID" access="field">
  <generator class="native"/>
</id>
<property name="DateTaken" column="DateTaken" />
<property name="ImageSource" column="ImageSource" />
<property name="ImageLocation" column="ImageLocation" />
<many-to-one name="GenericAttachment" class="Guru.Business.Entities.GenericAttachment, Guru.Business"  column="AttachmentID"  fetch="select" lazy="proxy" />

我在 SQL 服务器 2012 中使用 C#。

谢谢

您将 Table 2 的 ID 映射为本机 ID。这将使用底层数据库的默认实现。对于 SQL 服务器,这是身份。

native

picks identity, sequence or hilo depending upon the capabilities of the underlying database.

您想将映射更改为已分配并自行设置 ID。

如果确实是 one-one 映射,请更改您的映射以反映这一点。

此外,您编写的映射也没有多大意义。你不能让 child table 有一个重复的 PK,你可以通过添加 AttachmentID 作为 Table 2 的 PK 来做到这一点。

生成器 class "foreign" 解决了问题,更新了映射配置

Table 1(通用附件)

<id name="_id" column="AttachmentID" access="field">
  <generator class="identity"/>
</id>
<property name="FileName" update="false"/>
<property name="GroupID"/>
<many-to-one name="GenericAttachmentGroup" class="GenericAttachmentGroup" column="GroupID" fetch="select" cascade="none" not-null="false" update="false" insert="false"/>
<property name="RelativeStorageLocation"/>
<property name="FileSize"/>
<property name="FileStatus" />
<property name="StorageTypeID" column="StorageTypeID" />
<property name="DocumentId" not-null="false"/>
<property name="AccessKey" not-null="false"/>
<property name="AttachmentSource" column="AttachmentSource" />
<many-to-one name="Thumbnail" class="FileInformation" column="FileThumbnailID" fetch="select" cascade="save-update" not-null="false" not-found="ignore"/>
<one-to-one lazy="proxy" name="Metadata" class="GenericAttachmentMetadataDetails" fetch="select" cascade="save-update" outer-join="true" property-ref="GenericAttachment"/>

Table 2(GenericAttachmentMatadataDetails)

<id name="_id" column="AttachmentID" access="field">
  <generator class="foreign">
        <param name="property">GenericAttachment</param>
   </generator>
</id>
<property name="DateTaken" column="DateTaken" />
<property name="ImageSource" column="ImageSource" />
<property name="ImageLocation" column="ImageLocation" />
<many-to-one name="GenericAttachment" access="property" class="GenericAttachment" fetch="select" insert="false" update="false" cascade="none" column="AttachmentID" unique="true" />