使用 NHibernate 插入带有复合键的记录
我正在使用使用复合键的旧数据库。 我正在尝试使用 NHibernate 将新记录插入数据库。 NHibernate 指定我必须手动创建 ID,但是当我尝试使用此 ID 插入时,我收到消息:
System.Data.SqlClient.SqlException: Cannot insert explicit value for identity column in table 'tablename' when IDENTITY_INSERT is set to OFF.
我无法触摸任何数据库设置,因为它们是由美国总部管理的。
我发现我可以通过以下方式进行数据库插入:
insert into tablename (tablename_country_id, /*extra fields here*/) values (16, /*extra values here*/)
并且 tablename_id
列会自动递增。
是否可以编写某种处理程序,允许我使用 CountryId
集创建一个 ID
对象,并让它自动递增 Id
> 财产。
干杯。
示例代码:
表定义:
CREATE TABLE [dbo].[tablename](
[tablename_country_id] [int] NOT NULL,
[tablename_id] [int] IDENTITY(1,1) NOT NULL,
-- more fields here
CONSTRAINT [pk_tablename] PRIMARY KEY
(
[tablename_country_id] ASC,
[tablename_id] ASC
)
)
类文件:
public class ModelObject
{
public ID { get; set; }
// more properties here
}
public class ID : INHibernateProxy
{
public int Id { get; set; }
public int CountryId { get; set; }
public ILazyInitializer HibernateLazyInitializer { get { throw new ApplicationException(); } }
}
映射文件:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Model" assembly="API">
<class name="ModelObject" table="dbname.dbo.tablename" lazy="false">
<composite-id name="Id" class="ID">
<key-property name="Id" column="tablename_id" type="int" />
<key-property name="CountryId" column="tablename_country_id" type="int" />
</composite-id>
<!-- more properties here -->
</class>
</hibernate-mapping>
I am working with a legacy database that uses composite keys. And I am trying to use NHibernate to insert a new record into the database. NHibernate specifies that I have to create the Id manually, but when I try to insert with this id I get the message:
System.Data.SqlClient.SqlException: Cannot insert explicit value for identity column in table 'tablename' when IDENTITY_INSERT is set to OFF.
I cannot touch any of the db settings as they are administered by head office in USA.
I found that I can do a db insert via:
insert into tablename (tablename_country_id, /*extra fields here*/) values (16, /*extra values here*/)
and the tablename_id
column is automatically incremented.
Is it possible to write some sort of a handler that allows me to create an ID
object with the CountryId
set and have it auto-increment the Id
property.
Cheers.
Example Code:
Table Definition:
CREATE TABLE [dbo].[tablename](
[tablename_country_id] [int] NOT NULL,
[tablename_id] [int] IDENTITY(1,1) NOT NULL,
-- more fields here
CONSTRAINT [pk_tablename] PRIMARY KEY
(
[tablename_country_id] ASC,
[tablename_id] ASC
)
)
Class Files:
public class ModelObject
{
public ID { get; set; }
// more properties here
}
public class ID : INHibernateProxy
{
public int Id { get; set; }
public int CountryId { get; set; }
public ILazyInitializer HibernateLazyInitializer { get { throw new ApplicationException(); } }
}
Mapping File:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Model" assembly="API">
<class name="ModelObject" table="dbname.dbo.tablename" lazy="false">
<composite-id name="Id" class="ID">
<key-property name="Id" column="tablename_id" type="int" />
<key-property name="CountryId" column="tablename_country_id" type="int" />
</composite-id>
<!-- more properties here -->
</class>
</hibernate-mapping>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我认为您可以将身份列设置为复合键中的键之一。
我知道在 FluentnHibernate 中我有一个复合键的标识列名称
I Think you can set an identity column to one of your keys in the composite key.
i know that in fluentnhibernate i have a identity column name for a omposite key
也许这可能有效。 如果您显式添加更新语句,如果您需要将其更改为 sProc 或类似的内容,也可以。
这是存储过程概念的一个示例。
perhaps this may work. If you add the update statement explicitly, Also if you need to change it to a sProc or something like that you can.
here is an example of the sproc concept.
我知道您不能更改数据库表或约束,但是您绝对确定数据库对象确实意味着您必须使用 NHibernate 组合键吗?
NHibernate 复合键应用于那些行的唯一性由多个列确定的表。 在您提供的示例中,每行的唯一性实际上仅由单个 tablename_id 列确定。 主键被证明是多余的:也就是说,它不能被违反,因为它的组成元素之一是一个始终不同的标识列。
也许主键已被您的同事出于其他原因(索引等)放置在那里。
这意味着您的 NHibernate 映射实际上应该折叠为非常简单的东西:使用简单的 NHibernate 本机 id 生成器,使用单个 ID 映射到 tablename_id 的普通 POCO。 然后,CountryID 属性将您的省略属性作为普通属性加入以实现您的目标:CountryID 设置为由数据库自动递增的 ID。
I understand that you cannot alter the database table or constraints, but are you absolutely sure that the database objects really imply that you have to use an NHibernate composite key?
An NHibernate composite key should be used for those tables where the uniqueness of a row is determined by more than one column. In the example that you provided in turns out that the each row's uniqueness is actually only determined by the single tablename_id column. The primary key turns out to be superfluous: that is, it cannot be violated because one of its constituent elements is an identity column which will always be different.
Perhaps the primary key has been placed there by your colleagues for some other reason (indexing etc.).
This means that your NHibernate mapping should really collapse to something quite simple: a normal POCO with a single ID mapping to tablename_id using a simple NHibernate native id generator. The CountryID property then joins your ellided properties as a normal property to achive your aim: CountryID is set with ID auto-incremented by the database.
如Fluent nhibernate自动增量非键(Id)属性,可能不需要使用复合键来获取字段的生成性质。 考虑使用这个或类似的:
Map(x => x.Field).Column("Field").Generate.Always().ReadOnly();
as noted in fluent nhibernate auto increment non key (Id) property, it may not be necessary to use a composite key to get the generated nature of the field. Consider using this or similar to:
Map(x => x.Field).Column("Field").Generated.Always().ReadOnly();