2011-10-18 13 views
0

これはEntity Frameworkよりもはるかに幅広いSQLの話題ですが、私はこれらの両方の分野で非常に初心者ですが、Entity Frameworkの点でそれを尋ねます。エンティティフレームワーク多対8の関係

私は多対8の関係を執行したいと思います。

  • PersonGroupには8人の(一意の)Personが必要です。
  • 人物は多くの異なるPersonGroupsに存在することができます。
  • PersonGroupの順序は重要です(最初のものが最初に残る必要があります)。
  • 人がであるPersonGroup内のすべての人々とすべてのPersonGroupsに簡単にアクセスできますが

私は次のことを試してみた:。

1)は人とPersonGroup間の8つの1..manyの関連付けを追加します。 。私は確かにこのソリューションを使用して1グループあたり8人以上の人を持つことはできません。しかし、すべてのグループを見つけるためには、Personフィールドに8つ以上の変数を反復する必要がありますが、これは厄介です。

2)Personと一致するPersonGroupに8個のIDを追加します。もう一度、グループあたり8人しか保証できませんが、Person-> PersonGroupの関連付けによって自動的にリンクバックされることはありません。私は今それを2つの場所に確実に追加する必要があります。

3)多くの関係を行い、コードで処理します。これには2つの問題があります。グループあたり8人しか保証できません。注文が同じであることを保証できるかどうかは不明です。

これは最高ですか、どのような解決方法がありますか?

答えて

3

n:m関係:あなたはCHECK制約はあなたが(たとえば、MySQLを使用しますSQLエンジンで利用可能であることを確認する必要があり

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 

は、それがこのようなを持って信じるようにあなたをだますでしょうSQL-Serverはエラーを返しませんが、挿入しようとすると、チェックされた列にNULLが追加されます)

この方法には制限があります。 OrderingフィールドはNOT NULLである必要があります。NULLの場合は、8行以上(NULLを含む)を挿入できます(ただし、最大9行、8つの値、1つのNULLを持つSQLサーバーは例外です)。)

Orderingに最大8個の行とNULLを確保するには、MSDN site, CHECK Constraints(RDBMSにこのような機能がある場合)のような複雑な制約を設けることができますが、このような獣:

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に複数の位置を持つPersonが可能になります(ただし最大8個まで)。

3

多対多は私にとっては大丈夫です。トリガーを実装することで、グループあたり8人以下の人がいることを簡単に確認できます。また、ロジックにとって重要であると思われる場合は、この表に注文列を追加することもできます。 「キャッチ」と