NHibernate - 删除多对多关联

时间:2013-03-18 20:56:15

标签: nhibernate fluent-nhibernate many-to-many

我与用户和角色实体之间存在多对多关系,因此用户可以拥有多个角色,而角色可以与多个用户相关联。这是大多数具有用户和角色的应用程序的典型模型。我所有的关系都被定义为双向的。

我注意到如果我需要从用户添加/删除角色,那么我还需要从角色添加/删除用户,否则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>

0 个答案:

没有答案