我与用户和角色实体之间存在多对多关系,因此用户可以拥有多个角色,而角色可以与多个用户相关联。这是大多数具有用户和角色的应用程序的典型模型。我所有的关系都被定义为双向的。
我注意到如果我需要从用户添加/删除角色,那么我还需要从角色添加/删除用户,否则NHibernate无法识别添加/删除用户和角色之间的关联。因为我被迫有这样的方法:
public virtual void RemoveRole(Role role)
{
this.Roles.Remove(role);
role.Users.Remove (this);
}
public virtual void AddRole(Role role)
{
if (!role.Users.Contains(this))
{
role.Users.Add(this);
}
this.Roles.Add(role);
}
这些方法的问题在于,它们都会触发角色的“用户”列表上的延迟加载,而角色可以轻松拥有1000个用户,这使得它不可持续。我看到的两个选项是不使它们双向(不知道如何保存关联然后我猜)或使用原始sql将用户和角色之间的关联插入/删除到桥接表UserRoles中。由于我有很多这样的多对多实体,我试图看看这些场景是否有更好的可扩展选项。
我也使用流畅的Nhibernate进行基于约定的映射。
编辑:添加了映射信息(用户已被截断以删除不必要的属性),如果有帮助
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class xmlns="urn:nhibernate-mapping-2.2" name="PPS.Domain.Entities.User, PPS.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=24bfe5bf61a31130" table="Users">
<id name="Id" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" unsaved-value="0">
<column name="User_Id" />
<generator class="increment" />
</id>
<set cascade="all" collection-type="PPS.DataAccess.EntityCollectionFactory`1[[PPS.Domain.Entities.Role, PPS.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=24bfe5bf61a31130]], PPS.DataAccess, Version=1.0.0.0, Culture=neutral, PublicKeyToken=24bfe5bf61a31130" inverse="true" name="Roles" table="UserRoles">
<key>
<column name="User_Id" />
</key>
<many-to-many class="PPS.Domain.Entities.Role, PPS.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=24bfe5bf61a31130">
<column name="Role_id" />
</many-to-many>
</set>
<set cascade="all" collection-type="PPS.DataAccess.EntityCollectionFactory`1[[PPS.Domain.Entities.Company, PPS.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=24bfe5bf61a31130]], PPS.DataAccess, Version=1.0.0.0, Culture=neutral, PublicKeyToken=24bfe5bf61a31130" inverse="true" name="Companies" table="UserCompanies">
<key>
<column name="User_Id" />
</key>
<many-to-many class="PPS.Domain.Entities.Company, PPS.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=24bfe5bf61a31130">
<column name="Company_id" />
</many-to-many>
</set>
<property name="UserName" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="User_Name" />
</property>
<property name="Password" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Password" />
</property>
<property name="FirstName" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="First_Name" />
</property>
<property name="LastName" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Last_Name" />
</property>
<property name="ReceiveNotifications" type="YesNo">
<column name="Receive_Notifications" />
</property>
<property name="Marketing" type="YesNo">
<column name="Marketing" />
</property>
<property name="UserStatus" type="PPS.Domain.UserStatus, PPS.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=24bfe5bf61a31130">
<column name="User_Status_Id" />
</property>
<property name="UserType" type="PPS.Domain.UserType, PPS.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=24bfe5bf61a31130">
<column name="User_Type_Id" />
</property>
<property name="EmailAddress" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Email_Address" />
</property>
<property name="CreatedDate" type="System.DateTime, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Created_Date" />
</property>
<property name="LastLogin" type="System.DateTime, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Last_Login" />
</property>
<property name="LastUpdatedBy" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Last_Updated_By" />
</property>
<property name="LastUpdatedDate" type="System.DateTime, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Last_Updated_Date" />
</property>
<many-to-one cascade="save-update" class="PPS.Domain.Entities.Address, PPS.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=24bfe5bf61a31130" name="Address">
<column name="Address_Id" />
</many-to-one>
</class>
</hibernate-mapping>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class xmlns="urn:nhibernate-mapping-2.2" name="PPS.Domain.Entities.Role, PPS.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=24bfe5bf61a31130" table="Roles">
<id name="Id" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" unsaved-value="0">
<column name="Role_Id" />
<generator class="increment" />
</id>
<set cascade="all" collection-type="PPS.DataAccess.EntityCollectionFactory`1[[PPS.Domain.Entities.User, PPS.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=24bfe5bf61a31130]], PPS.DataAccess, Version=1.0.0.0, Culture=neutral, PublicKeyToken=24bfe5bf61a31130" name="Users" table="UserRoles">
<key>
<column name="Role_Id" />
</key>
<many-to-many class="PPS.Domain.Entities.User, PPS.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=24bfe5bf61a31130">
<column name="User_id" />
</many-to-many>
</set>
<property name="Name" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Name" />
</property>
<property name="Rank" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Rank" />
</property>
<property name="IsInternal" type="YesNo">
<column name="Is_Internal" />
</property>
</class>
</hibernate-mapping>