我正在轮询多个系统(域)以获取安全信息,因此我正在处理domainUsers及其角色。我的实体设置如下图所示,但是我在设置AutoMapper覆盖中的domainUser.HasMany关系时遇到了麻烦。
你会注意到我没有domainUser.DomainUserId和role.RoleId这使得这更简单(没有compositeIds。)我已经避免了这些字段,因为我已经有了一个自然的复合键,它会当我从下游域中提取此数据时,请填充。如果我添加这些人工密钥,我必须在调用session.Merge(domainUser)之前预先获取它们的值。我试图避免这样做。
实体对象很明显(我希望),但这就是我所拥有的。
public class DomainUser
{
public virtual int Domain_Id { get; set; }
public virtual string DomainUserLogin { get; set; }
public virtual string EmployeeId { get; set; }
// extra field removed for breviety
public DomainUser()
{
this.Roles = new List<DomainUserRole>();
}
public virtual void AddRole(DomainUserRole role)
{
role.DomainUser = this;
this.Roles.Add(role);
}
// overrides for equals and getHashCode
}
和
public class DomainUserRole
{
public virtual DomainUser DomainUser { get; set; }
public virtual string DataSegment { get; set; } // Some group of data a user has access to, like US or China
public virtual string RoleName { get; set; }
public virtual string RoleDescription { get; set; }
// extra field removed for breviety
// overrides for equals and getHashCode
}
我的数据库架构非常简单。
alt text http://lh6.ggpht.com/_MV6QGBD11JE/S3iX2qcP_jI/AAAAAAAAEE0/PGIO07BlCSo/s800/Untitled.gif.jpg
我已经像这样启动了IAutoMappingOverride类。但是,我不知道如何为角色设置hasMany。它一直在给我
NHibernate.FKUnmatchingColumnsException:
Foreign key (FK20531BE4163641BB:tblDomainUserRoles [DomainUser]))
must have same number of columns as the referenced primary key
(tblDomainUsers [Domain_Id, DomainUserLogin]).
如何设置该外键以同时使用这两个字段?
public class DomainUserMap : IAutoMappingOverride<DomainUser>
{
public void Override(AutoMapping<DomainUser> mapping)
{
mapping.CompositeId()
.KeyProperty(user => user.Domain_Id, "Domain_Id")
.KeyProperty(user => user.DomainUserLogin, "DomainUserLogin");
// I"ve tried this.
// mapping.HasMany(x => x.Roles)
// .KeyColumns.Add("Domain_Id")
// .KeyColumns.Add("DomainUserLogin");
// also tried this where I define this FK in DB with both fields.
// mapping.HasMany(x => x.Roles)
// .ForeignKeyConstraintName("FK_tblDomainUserRoles_tblDomainUsers")
}
}
public class DomainUserRoleMap : IAutoMappingOverride<DomainUserRole>
{
public void Override(AutoMapping<DomainUserRole> mapping)
{
mapping.CompositeId()
.KeyReference(role => role.DomainUser)
.KeyProperty(role => role.DataSegment)
.KeyProperty(role => role.RoleName);
}
}
答案 0 :(得分:0)
您可能想要使用复合键类。
使用密钥类here at SO的示例。您可能必须下拉并使用HBM文件,而不是使用Fluent NHibernate。
答案 1 :(得分:0)
我做了最终手动编辑hbm文件。看起来最流行的Nhibernate构建解决了这个问题。这是我的hbm文件的样子。
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true">
<class xmlns="urn:nhibernate-mapping-2.2" name="AAA.Core.Entities.DomainUser, AAA.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`tblDomainUsers`">
<composite-id mapped="false" unsaved-value="undefined">
<key-property name="Domain_Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Domain_Id" />
</key-property>
<key-property name="DomainUserLogin" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="DomainUserLogin" />
</key-property>
</composite-id>
... properties hidden for breviety
<bag inverse="true" cascade="all-delete-orphan" lazy="false" name="Roles">
<key>
<column name="Domain_Id" />
<column name="DomainUserLogin" />
</key>
<one-to-many class="AAA.Core.Entities.DomainUserRole, AAA.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</bag>
</class>
</hibernate-mapping>
这是角色的文件。
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true">
<class xmlns="urn:nhibernate-mapping-2.2" name="AAA.Core.Entities.DomainUserRole, AAA.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`tblDomainUserRoles`">
<composite-id mapped="false" unsaved-value="undefined">
<key-property name="DataSegment" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="DataSegment" />
</key-property>
<key-property name="RoleName" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="RoleName" />
</key-property>
<key-many-to-one name="DomainUser" class="AAA.Core.Entities.DomainUser, AAA.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<column name="Domain_Id" />
<column name="DomainUserLogin" />
</key-many-to-one>
</composite-id>
... properties hidden for breviety
</class>
</hibernate-mapping>