我正在使用使用复合键的旧数据库。我正在尝试使用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
列会自动递增。
是否可以编写某种处理程序,允许我使用ID
集创建CountryId
对象,并让它自动增加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>
答案 0 :(得分:0)
我认为您可以将标识列设置为复合键中的一个键。
我知道在fluentnhibernate中我有一个omposite键的标识列名称
答案 1 :(得分:0)
https://www.hibernate.org/hib_docs/nhibernate/1.2/reference/en/html/querysql.html#querysql-cud
这是一个sproc概念的例子。
<class name="Person">
<id name="id">
<generator class="increment"/>
</id>
<property name="name" not-null="true"/>
<sql-insert>exec createPerson ?, ?</sql-insert>
<sql-delete>exec deletePerson ?</sql-delete>
<sql-update>exec updatePerson ?, ?</sql-update>
</class>
答案 2 :(得分:0)
我知道你不能改变数据库表或约束,但是你绝对确定数据库对象真的暗示你必须使用NHibernate复合键吗?
NHibernate复合键应该用于那些行的唯一性由多个列确定的表。在您提供的示例中,每行的唯一性实际上仅由单个tablename_id列确定。主键证明是多余的:也就是说,它不能被违反,因为它的一个组成元素是一个永远不同的标识列。
也许主要关键因为其他原因而被同事放在那里(索引等)。
这意味着你的NHibernate映射应该真正崩溃到一个非常简单的东西:一个普通的POCO,使用一个简单的NHibernate本机id生成器将一个ID映射到tablename_id。然后,CountryID属性将您的ellided属性作为普通属性加入以实现您的目标:CountryID设置为ID由数据库自动递增。
public class ModelObject
{
public int ID { get; set; }
public int CountryID { get; set; }
// more properties here
}
<?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">
<id name="ID" column="tablename_id" type="int">
<generator class="native" />
</id>
<property name="CountryID" column="tablename_country_id" type="int" />
<!-- more properties here -->
</class>
</hibernate-mapping>
答案 3 :(得分:0)
如fluent nhibernate auto increment non key (Id) property中所述,可能没有必要使用复合键来获得字段的生成性质。考虑使用这个或类似的:
Map(x =&gt; x.Field).Column(&#34; Field&#34;)。Generated.Always()。ReadOnly();