0

我有 2 个具有多对多关系的表。用户可以有很多组,组可以有很多用户。

public class User
{
   public virtual Guid Id { get; set; }
   public virtual UInt64 UserId { get; set; }
   public virtual IList<Group> Groups{ get; set; }
}

public class Group
{
   public virtual Guid Id { get; set; }
   public virtual Guid GroupGuid  { get; set; }
}

我使用 Fluent NHibernate 来自动映射它们,如下所示:

.Override<User>(obj => obj.HasManyToMany(x => x.Groups).Table("UserToGroup").Cascade.AllDeleteOrphan())

结果 Nhibernate 生成 3 个表:1.用户 - 映射对象表 2. 组映射对象表 3. UserToGroup - 生成的关联表

要求是在这些表上具有以下功能: 1. AddUser(UInt64 UserId, IEnumerable groups) 2. RemoveGroup(GroupGuid groupGuild) 3. Dictionary> GetGroupToUsers();

AddUser 方法正常工作,所有表已更新正常: * 在 User 表中插入新用户。OK * 在组表中插入新组。OK * 在 UserToGroup 表中插入新的关系记录。好的

我使用以下代码添加用户(包括组):

public void AddUser(User userData, IList<Guid> groupIds)
{
   User user = new User();
   user.UserId = userData.UserId;

   IList<User> Users = new List<Users();
   Users.Add(user);

   IList<Group> groups = new List<Group>();

   foreach (Guid groupId in groupIds)
   {
      Group grp = new Group();
      grp.GroupGuid = groupId;
      grp.Users = Users;
      groups.Add(grp);
   }

   user.Groups = groups;
   Session.Save(user);
}

我使用以下代码删除组:

public void RemoveGroup(GroupGuid groupGuild)
{
     IList<Group> groupsToRemove = Session.QueryOver<Group>().Where(
            row => row.GroupGuid == groupGuild).List();
     foreach (Group group in groupsToRemove)
     {
          group.Users.Clear();
          Session.Delete(group);
     }
}

RemoveGroup 方法失败,出现以下异常:

threw exception: 
NHibernate.Exceptions.GenericADOException: could not delete: [StorageObject.Group#11111111-1111-1111-1111-111111111111][SQL: DELETE FROM "Group" WHERE Id = ?] ---> System.Data.SqlServerCe.SqlCeException: The primary key value cannot be deleted because references to this key still exist. [ Foreign key constraint name = FK4B29424018FA0CD4 ]

我了解不能删除 Group 表,因为引用 UserToGroup 表指向 Group 表。

  1. 第一个问题:我怎样才能让休眠来理解我希望能够从双方控制这种多对多关系:添加用户和组 - 从用户端。并删除组 - 从组方面

我试图将 Inverse 移动到 User 表,但在这种情况下,当我添加 User 时,关联表不会被填充。

定义这种多对多关系的最佳方法是什么?

更新:我尝试的另一种方法是在此配置中的组中也有用户列表 removeGroup 是 wokring 但 addUser 不适用于特定场景:

public class Group
{
   public virtual Guid Id { get; set; }
   public virtual Guid GroupGuid  { get; set; }
   public virtual IList<User> Users{ get; set; }
}

public class User
{
   public virtual Guid Id { get; set; }
   public virtual UInt64 UserId { get; set; }
   public virtual IList<Group> Groups{ get; set; }
}

现在我有一个双向的多对多。我的流利映射是:

.Override<User>(obj => obj.HasManyToMany(x => x.Groups).ParentKeyColumn("UserId").ChildKeyColumn("GroupId").Table("UserToGroup").Cascade.SaveUpdate()
.Override<Group>(obj => obj.HasManyToMany(x => x.Users).ParentKeyColumn("GroupId").ChildKeyColumn("UserId").Table("UserToGroup")

如果我使用此配置 RemoveGroup 工作正常,但 AddUser 不适用于以下情况:当添加包含相同组的 2 个用户时,关联表删除第一个关系并仅保留最后一个引用,而不是同时拥有两个关系。请指教。

4

1 回答 1

1

尝试在 Group 中添加一个逆向集合:

public class Group
{
    public virtual Guid Id { get; set; }
    public virtual Guid GroupGuid  { get; set; }
    public virtual IList<User> Users { get; set; }
}

在您的映射中:

.Override<Group>(obj => obj.HasManyToMany(x => x.Users).Table("UserToGroup").Inverse().Cascade.SaveUpdate())

您的删除方法:

public void RemoveGroup(GroupGuid groupGuild)
{
     IList<Group> groupsToRemove = Session.QueryOver<Group>().Where(
            row => row.GroupGuid == groupGuild).List();
     foreach (Group group in groupsToRemove)
     {
          group.Users.Clear();   // Removes references from all users pointing to that group
          Session.Delete(group);
     }
}

提交事务时,应自动删除引用。我自己从未尝试过,但它可能对你有用。

于 2012-06-13T17:30:30.853 回答