2012-06-13 2 views
0

manyToMany 관계가있는 2 개의 테이블이 있습니다. 사용자는 많은 그룹을 가질 수 있고 그룹에는 많은 사용자가있을 수 있습니다.NHibernate : 양방향 ManyToMany 제어. 하나의 엔티티에서 추가하고 다른 엔티티에서 제거

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; } 
} 

나는 다음과 같이 그들을 오토 할 유창함 자 NHibernate를 사용

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

결과 NHibernate에 3 개 테이블 생성 : 1. 사용자 - 매핑 된 객체 테이블 2 그룹 매핑 개체 테이블 3. UserToGroup - 생성 된 연결 테이블

이 테이블에는 다음과 같은 기능이 필요합니다. 1. AddUser (UInt64 UserId, IEnumerable 그룹) 2. RemoveGroup (GroupGuid groupGuild) 3. 사전> GetGroupToUsers();

AddUser 메서드가 작동합니다. 확인, 모든 테이블이 업데이트되었습니다. 확인 : * 사용자 테이블에 새 사용자가 삽입되었습니다. OK * 그룹 테이블에 새 그룹을 삽입하십시오. OK * UserToGroup 테이블에 새 관계가 삽입됩니다.

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 방법은 다음과 같은 예외로 실패 : I 그룹 제거하려면 다음 코드를 사용

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); 
} 

: OK

나는 (그룹 포함) 사용자를 추가하려면 다음 코드를 사용 :

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 ] 

나는 그룹 테이블을 참조하기 때문에 삭제 될 수 없음을 이해 UserToG roup 테이블이 그룹 테이블을 가리 킵니다.

  1. 첫번째 질문 : 그룹에 사용자를 추가 - 사용자 측면에서 : 나는 두 측면에서이 manyToMany 관계를 컨트롤러 할 수 있도록하려는 것을 이해하는 것이 최대 절전 모드로 만들 수있는 방법. 그룹에서 그룹을 삭제하십시오.

사용자 테이블을 역으로 이동하려고 시도했지만이 경우 사용자를 추가하면 연관 테이블이 채워지지 않습니다.

이러한 종류의 manyToMany 관계를 정의하는 가장 좋은 방법은 무엇입니까?

업데이트 : 시도 또 다른 방법이 구성 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") 

나는 잘 작동하지만, adduser 명령은 다음과 같은 경우에 작동하지 않습니다 RemoveGroup이 구성을 사용하는 경우 : 를 처음 관계를 삭제 같은 그룹에게 연결 테이블을 포함 2 사용자를 추가 할 때와 보유를 두 관계를 갖는 대신에 단지 마지막 참조. 알려주십시오.

답변

1

봅니다 그룹에 역 모음을 추가합니다 :

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); 
    } 
} 

당신이 트랜잭션을 커밋, 참조를 자동으로 제거되어야합니다. 나는 이것을 나 자신으로 시도한 적이 없지만 그것은 당신을 위해 일할 수도 있습니다.

+0

나는 당신이 제안한 것을했으나 동일한 예외가 발생했습니다. 그룹을 삭제할 수 없습니다. 연관 테이블에서이 키에 대한 참조가 있으므로 삭제할 수 없습니다. – Haimon

+0

예기치 않은 다른 오류가있는 다른 매핑 구성으로 질문을 업데이트했습니다. – Haimon

+1

삭제하기 전에 그룹을 먼저 저장해야 할 수도 있습니다. – rumpelstiefel

관련 문제