3

Apple テーブルと Orange テーブルの間に多対多の関係があります。

public class Apple
{
    [Key]
    public int AppleID { get; set; }

    [Required]
    public string AppleName { get; set; }

    [NotMapped]
    public int[] SelectedOranges { get; set; }

    public virtual ICollection<Orange> Oranges { get; set; }

}

public class Orange
{

    [Key]
    public int OrangeID { get; set; }
    public String OrangeName { get; set; }
    public virtual ICollection<Apple> Apples { get; set; }
}

Data Context クラスでは、OnModelCreating メソッドは以下のようにオーバーライドされます。

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        //----------------------------------------------------------------
        //Creating a Association (Intermediate Table) which
        //will hold M2M relations from Student to Course.
        //----------------------------------------------------------------

        modelBuilder.Entity<Apple>()
            .HasMany(c => c.Oranges)
            .WithMany(t => t.Apples);
    }

コントローラーから編集した値を ASP.NET MVC アプリケーションに保存すると、次の例外が発生します。

リレーションシップの外部キー プロパティを公開しないエンティティの保存中にエラーが発生しました。1 つのエンティティを例外のソースとして識別できないため、EntityEntries プロパティは null を返します。保存中の例外の処理は、エンティティ タイプで外部キー プロパティを公開することで簡単に行うことができます。詳細については、InnerException を参照してください。

内部例外は次のとおりです。

PRIMARY KEY 制約 'PK_dbo.AppleOranges' に違反しています。オブジェクト 'dbo.AppleOranges' に重複するキーを挿入できません。重複するキーの値は (1, 3) です。\r\nステートメントは終了しました。

何か案が?

アップルコントローラ:

    //
    // GET: /Apple/Edit/5

    public ActionResult Edit(int id = 0)
    {

        Apple Apple = db.Apples.Find(id);
        if (Apple == null)
        {
            return HttpNotFound();
        }
        var selectedvalues = new List<Orange>();
        Apple.SelectedOranges = new int[Apple.Oranges.Count];
        int j=0;
        foreach (var i in Apple.Oranges)
        {
            selectedvalues.Add(i);
            Apple.SelectedOranges[j++] = db.Oranges.ToList().IndexOf(i)+1;
        }
        ViewBag.OrangesList = new MultiSelectList(db.Oranges, "OrangeID", "OrangeName", selectedvalues);
        return View(Apple);
    }

    //
    // POST: /Apple/Edit/5

    [HttpPost]
    public ActionResult Edit(Apple Apple)
    {
        if (ModelState.IsValid)
        {
            db.Entry(Apple).State = EntityState.Modified;
            foreach (var i in Apple.SelectedOranges)
            {
                if (Apple.Oranges == null)
                    Apple.Oranges = new List<Orange>();
                Apple.Oranges.Add(db.Oranges.Find(i));
            }
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        ViewBag.OrangesList = new MultiSelectList(db.Oranges, "OrangeID", "OrangeName", Apple.SelectedOranges);
        return View(Apple);
    }

アップル編集ビュー:

@using (Html.BeginForm()) {
@Html.ValidationSummary(true)

<fieldset>
    <legend>Apple</legend>

    @Html.HiddenFor(model => model.AppleID)

    <div class="editor-label">
        @Html.LabelFor(model => model.AppleName)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.AppleName)
        @Html.ValidationMessageFor(model => model.AppleName)
    </div>


    <div class="editor-label">
        @Html.LabelFor(model => model.Oranges)
    </div>
    <div class="editor-field">
        @Html.ListBoxFor(m=>m.SelectedOranges,(MultiSelectList)ViewBag.OrangesList)
        @Html.ValidationMessageFor(model => model.Oranges)
    </div>

    <p>
        <input type="submit" value="Save" />
    </p>
</fieldset>

}

4

1 に答える 1

8

Apple.Orangesアイテムを追加する前に、最初にロードする必要があります。コレクションが読み込まれると、EF の変更トラッカーは、新しい関連付けと既存の関連付けを認識し、新しい関連付けのみが保存されます。

コレクションをロードするには

db.Entry(Apple).Collection(a => a.Oranges).Load()

そして、あなたはコードを削除することができます

if (Apple.Oranges == null)
    Apple.Oranges = new List<Orange>();
于 2013-07-10T07:33:07.943 に答える