Nhibernate 多对多映射 中间表的主键问题1,我原来的主键采用int自增长方式,中间表主键也采用自增int,运行没有问题。
2,但是因为主键为自增型,对于多数据库的同步有问题,所以改为采用36位的无重复数。
所有主键都改为36位的无重复数后, 测试报错。 大概意思是 nhibernate生成插入中间表SQL时,并没有生成ID,(从映射的意思来看,nhibernate也的确不知道 中间表主键的生成方式,所以也不会生成中间表ID;自增类型,不需要生成中间表ID,所以没有这个问题) 3,我把中间表的ID去掉后,数据就能保存成功了。但是又会在数据表中产生重复的记录。若把中间表两外键组合为主键时,插入相同数据时,会报关联约束错误的。
以上情况,导致多对多映射,采用32位无重复数ID时,会遇到上述问。请问 前辈们遇到此类情况是怎样处理的?小弟先谢过了!
2,但是因为主键为自增型,对于多数据库的同步有问题,所以改为采用36位的无重复数。
所有主键都改为36位的无重复数后, 测试报错。 大概意思是 nhibernate生成插入中间表SQL时,并没有生成ID,(从映射的意思来看,nhibernate也的确不知道 中间表主键的生成方式,所以也不会生成中间表ID;自增类型,不需要生成中间表ID,所以没有这个问题) 3,我把中间表的ID去掉后,数据就能保存成功了。但是又会在数据表中产生重复的记录。若把中间表两外键组合为主键时,插入相同数据时,会报关联约束错误的。
以上情况,导致多对多映射,采用32位无重复数ID时,会遇到上述问。请问 前辈们遇到此类情况是怎样处理的?小弟先谢过了!
create table A_FunctionMenu (
ID char(36) not null,
ParentID char(36) null,
ApplicationID char(36) null,
Level int not null,
SearchCode varchar(64) not null,
FunctionName varchar(64) not null,
IsMenu bit not null,
MenuURL varchar(256) null,
Type char(2) not null,
CreateType char(2) not null,
Sort int not null,
AddTime datetime null,
UpdateTime datetime null,
IsShow bit not null,
constraint PK_A_FUNCTIONMENU primary key (ID)
)角色表
create table A_Role (
ID char(36) not null,
RoleName varchar(128) not null,
Sort int not null,
Re varchar(512) null,
IsShow bit not null,
constraint PK_A_ROLE primary key (ID)
)
go角色和功能的中间表
create table A_RoleFunctionMenu (
ID char(36) not null,
RoleID char(36) not null,
FunctionMenuID char(36) not null,
constraint PK_A_ROLEFUNCTIONMENU primary key (ID)
)
映射文件
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="Sight.Model.Admin.RoleEntity, Sight.Model.Admin" table="A_Role" >
<id name="ID" access="property">
<column name="ID" sql-type="char(36)" not-null="true"/>
<generator class="uuid.hex">
<param name="format">D</param>
<param name="seperator">-</param>
</generator>
</id>
<property name="RoleName" column="RoleName" type="String" length="128" />
<property name="Re" column="Re" type="String" length="512" />
<property name="Sort" column="Sort" type="Int32" length="4" />
<property name="IsShow" column="IsShow" type="Boolean"/> <bag name="FunctionMenus" table="A_RoleFunctionMenu" >
<key column= "RoleID" />
<many-to-many class="Sight.Model.Admin.FunctionMenuEntity,Sight.Model.Admin" column="FunctionMenuID" />
</bag> </class></hibernate-mapping><?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="Sight.Model.Admin.FunctionMenuEntity, Sight.Model.Admin" table="A_FunctionMenu" >
<id name="ID" access="property">
<column name="ID" sql-type="char(36)" not-null="true"/>
<generator class="uuid.hex">
<param name="format">D</param>
<param name="seperator">-</param>
</generator>
</id>
<!--property name="ParentID" column="ParentID" type="Int32" length="4" /-->
<property name="Level" column="Level" type="Int32" length="4" />
<property name="SearchCode" column="SearchCode" type="String" length="64" />
<property name="FunctionName" column="FunctionName" type="String" length="64" />
<property name="IsMenu" column="IsMenu" type="Boolean" />
<property name="MenuURL" column="MenuURL" type="String" length="256" />
<property name="Type" column="Type" type="String" length="2" />
<property name="CreateType" column="CreateType" type="String" length="2" />
<property name="Sort" column="Sort" type="Int32" length="4" />
<property name="AddTime" column="AddTime" type="DateTime"/>
<property name="UpdateTime" column="UpdateTime" type="DateTime"/>
<property name="IsShow" column="IsShow" type="Boolean"/> <many-to-one name="ParentFunctionMenu" column="ParentID" /> <bag name="ChildFunctionMenus" order-by="Sort desc" cascade="all" lazy="true">
<key column="ParentID" />
<one-to-many class="Sight.Model.Admin.FunctionMenuEntity, Sight.Model.Admin" />
</bag> <bag name="HasRoles" table="A_RoleFunctionMenu" lazy="true">
<key column="FunctionMenuID" />
<many-to-many class="Sight.Model.Admin.RoleEntity,Sight.Model.Admin" column="RoleID" />
</bag> </class></hibernate-mapping>运行测试方法: public void AddFunctionAddRoleTest()
{
FunctionMenuBLL functionMenuBLL = new FunctionMenuBLL();
FunctionMenuEntity functionMenuEntity = new FunctionMenuEntity();
functionMenuEntity.FunctionName = "权限管理";
functionMenuBLL.Add(functionMenuEntity); RoleBLL roleBLL = new RoleBLL();
RoleEntity role = new RoleEntity();
role.RoleName = "校长";
role.IsShow = true; role.FunctionMenus.Add(functionMenuEntity); roleBLL.Add(role);
}
NHibernate: INSERT INTO A_Role (RoleName, Re, Sort, IsShow, ID) VALUES (@p0, @p1, @p2, @p3, @p4); @p0 = '校长', @p1 = '', @p2 = '0', @p3 = 'True', @p4 = '6612ad26-306f-4259-8490-96e83bddfa81'
NHibernate: INSERT INTO A_RoleFunctionMenu (RoleID, FunctionMenuID) VALUES (@p0, @p1); @p0 = '6612ad26-306f-4259-8490-96e83bddfa81', @p1 = 'c4400f86-bd15-4aed-9660-a6399d4ea33d'
TestCase 'M:Sight.Test.Admin.RoleTest.AddFunctionAddRoleTest'
failed: could not insert collection: [Sight.Model.Admin.RoleEntity.FunctionMenus#6612ad26-306f-4259-8490-96e83bddfa81]
NHibernate.ADOException: could not insert collection: [Sight.Model.Admin.RoleEntity.FunctionMenus#6612ad26-306f-4259-8490-96e83bddfa81] ---> System.Data.SqlClient.SqlException: 无法将 NULL 值插入列 'ID',表 'Sight.dbo.A_RoleFunctionMenu';该列不允许空值。INSERT 失败。
语句已终止。
在 System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
在 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
在 System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
在 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
在 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
在 System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
在 System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
在 NHibernate.Impl.NonBatchingBatcher.AddToBatch(IExpectation expectation)
在 NHibernate.Persister.Collection.AbstractCollectionPersister.Recreate(IPersistentCollection collection, Object id, ISessionImplementor session)
--- 内部异常堆栈跟踪的结尾 ---
在 Sight.Tool.DataAccess.DAL.SessionManager.Add[T](T entity) 位置 D:\project\SightProject\Sight\Tool\DataAccess\DAL\SessionManager.cs:行号 165
在 Sight.Tool.BusinessService.BaseBLL`2.Add(T entity) 位置 D:\project\SightProject\Sight\Tool\BusinessService\BaseBLL.cs:行号 32
在 Sight.Test.Admin.RoleTest.AddFunctionAddRoleTest() 位置 D:\project\SightProject\Sight\Test\Admin\RoleTest.cs:行号 690 passed, 1 failed, 0 skipped, took 6.08 seconds.