7

次の投稿によると、Entity Framework (最初にコード) で多対多の関係を作成しようとしています: MVC と Entity Framework の限られた数の選択肢のためのデータベース設計?

しかし、私はそれを正しく動作させることができず、非常に単純なことを間違った方法で行っていると確信しています. ここに私の試みから持っていない図があります:

ここに画像の説明を入力

ジャンクション テーブルの要点は、リレーションシップに追加のプロパティ Level が必要であるため、コンサルタントとプログラムの間の直接的なリレーションシップだけを使用することはできません。デザイナーに ConsultantProgramLink エンティティを手動で追加し、Program と Consultant にそれぞれ関連付けを追加し、それぞれに FK を追加することを選択して、両方を主キーにしました。しかし、このようにすると、期待どおりに動作しません。

Consultant と Program を直接関連付けていれば、コード内でたとえば Consultant.Programs を参照できたはずです。しかし、それはジャンクション テーブルでは機能しません。これを解決する方法はありますか、それとも常にジャンクション プロパティ (Consultant.ConsultantProgramLink.Programs) を使用する必要がありますか? いずれにせよ、junction プロパティを通過しようとしても役に立ちません。私のコードで Consultant.ConsultantProgramLink を実行できますが、別のドットではナビゲーション プロパティ Programs が表示されません (何らかの理由で単に Programs になったのはなぜですか?最終的にそれらにアクセスできるようになったら、名前を変更できますか?) .

それで、私は何を間違っていますか?コードでドット表記を使用してプロパティにアクセスできないのはなぜですか?

4

1 に答える 1

11

ジャンクション テーブルをエンティティとしてモデル化すると、 と の間の直接的な多対多の関係が失われConsultantますProgram。それがどのように機能するかです。ジャンクション テーブルには、直接の多対多の関係または追加のプロパティがあります。両方ではありません。両方が必要な場合は、でカスタムProgramsプロパティを作成しConsultant、linq クエリを使用して関連するプログラムを取得できます。

public IEnumerable<Program> Programs
{
    get
    {
        return this.ConsultantProgramLinks.Select(l => l.Program);   
    }
}

この例は、最後の問題の説明でもあります。Programプロパティを on にすることはできませんConsultantProgramLink。これは、単一のエンティティではなく、関連するエンティティのコレクションであるためです ( と呼ばれる必要がありますConsultantProgramLinks)。エンティティのプロパティは、コレクションではなく単一のエンティティを表すため、ConsultantProgramLink単に呼び出されます。Program

編集:

それぞれProgramを自動的に関連付ける必要があるConsultant場合は、新しい を作成するときに強制する必要がありますProgram。ジャンクション テーブルを別のエンティティとして公開すると、おそらく簡単に実現できます。

var program = new Program();
...
context.Programs.AddObject(program);

var ids = from c in context.Consultants
          select c.Id;

foreach (var id in ids)
{
    var link = new ConsultantProgramLink
        {
            ConsultantId = id,
            Program = program
        };
    context.ConsultantProgramLinks.AddObject(link);
}

context.SaveChanges();

新規追加する場合Consultantは、すべてのプログラムへのリンクを同じ方法で作成する必要があります。

欠点は、たとえば 1000 人のコンサルタントがいる場合、この構成により 1001 のデータベース挿入が作成され、各挿入がデータベースへの個別のラウンドトリップで実行されることです。これを回避するには、プログラム テーブルでストアド プロシージャまたはトリガーを使用するしかありません。

于 2011-03-24T11:40:34.160 に答える