2011-10-18 2 views
0

이것은 Entity Framework보다 훨씬 광범위한 SQL 주제 일 수 있습니다.이 두 가지 영역의 초보자이지만 Entity Framework 측면에서 묻습니다.Entity Framework 다 대다 관계?

저는 다 대다 관계를 시행하고 싶습니다. 내 설정은 다음과 같습니다.

  • PersonGroup에는 8 명의 (고유 한) 개인이 필요합니다.
  • 사람이 여러 다른 PersonGroup에있을 수 있습니다.
  • PersonGroup의 순서가 중요합니다 (첫 번째 항목은 처음으로 유지해야 함 등). .

    1) 는 사람과 PersonGroup 사이에 8 개 1..many 연결을 추가하십시오 PersonGroup에있는 모든 사람과 사람의 모든 PersonGroups에

  • 쉽게 접근

나는 다음 시도했다 .이 솔루션을 사용하면 그룹당 8 명을 초과 할 수 없습니다. 그러나 모든 그룹을 찾으려면 사람 필드에 8 개 이상의 변수를 반복해야하는데, 이는 까다 롭습니다.

2) 사람과 일치하는 PersonGroup에 8 개의 ID를 추가하십시오. 다시 한 번, 그룹 당 8 명만 보장 할 수 있지만 Person-> PersonGroup의 연결을 통해 자동으로 다시 연결되는 링크는 없습니다. 이제 두 곳에 추가해야합니다.

3) 많은 ... 많은 관계를 수행하고 코드에서 처리하십시오. 두 가지 문제가 있습니다. 그룹당 8 명만을 보장 할 수는 없으며 주문이 동일하게 유지되는지 확신 할 수없는 것입니다.

그래서 가장 좋으며, 어떤 해결책이 있습니까?

답변

3

는 "캐치"를 가진 n:m 관계 :

Person 
------ 
PersonId 
PRIMARY KEY (PersonId) 


PersonGroup 
----------- 
GroupId 
PRIMARY KEY (GroupId) 


Belongs 
------- 
GroupId 
PersonId 
Ordering 

PRIMARY KEY (GroupId, PersonId) 
FOREIGN KEY (GroupId) 
    REFERENCES PersonGroup (GroupId) 
FOREIGN KEY (PersonId) 
    REFERENCES Person (PersonId)    --- all normal up to here 

UNIQUE KEY (GroupId, Ordering)    --- the "catch" 
CONSTRAINT Ordering_chk      --- ensuring only up to 8 persons 
    CHECK Ordering IN (1,2,3,4,5,6,7,8)  --- per group 

당신은 CHECK 제약은 사용거야 SQL 엔진에 사용할 수 있는지 확인해야한다 (MySQL은 예를 들어, 그러한 가지고 믿음으로 당신을 속일 것 SQL-Server는 오류를 반환하지 않지만 실제로 열을 삽입하려고하면 확인 열에 NULL을 추가합니다.

이 방법에는 제한이 있습니다. Ordering 필드는 NOT NULL이어야합니다. NULL 인 경우 8 개 이상의 행 (NULL 포함)을 삽입 할 수 있기 때문입니다 (최대 9 개의 행, 값 8 개 및 NULL을 허용하는 SQL Server 제외).) 당신의 RDBMS는 기능이있는 경우

Ordering 8 행과 널 (NULL)의 최대 값을 보장하기 위해, 당신은 (MSDN site, CHECK Constraints에 설명 된 것과 같은 더 복잡한 제약 조건을 만들 수)하지만 난의 성능에 전혀 모르겠어요 이러한 짐승

CREATE FUNCTION CheckMax8PersonPerGroup() 
RETURNS int 
AS 
BEGIN 
    DECLARE @retval int 
    SELECT @retval = CASE WHEN EXISTS 
           (SELECT * 
           FROM Belongs 
           GROUP BY GroupId 
           HAVING COUNT(*) > 8 
          ) 
         THEN 0 
         ELSE 1 
        END 
    RETURN @retval 
END; 
GO 
ALTER TABLE Belongs 
ADD CONSTRAINT Ordering_chk 
     CHECK (CheckMax8PersonPerGroup() = 1); 
GO 

제약이 대안 8 개 행이 기준 테이블에 FOREIGN KEY로 생성 될 수있다. (당신이 MySQL을 사용하는 경우, 그. CHECK에 해당이 할 수있는 유일한 방법입니다)


변형은 기본 키로 (GroupId, Ordering)를 사용하고 (GroupId, PersonId) 조합에 어떤 제약이없는하는 것입니다. 이렇게하면 Group (최대 8 자까지)에 여러 위치가있는 Person이 허용됩니다.

3

다 대다는 나에게 좋아 보인다. 트리거를 구현하여 그룹당 8 명을 넘지 않도록 할 수 있습니다. 또한 논리가 중요하다고 생각하면이 테이블에 주문 열을 추가 할 수 있습니다.