最初にコンテキストからアイテムをロードしてからクリアすることにより、クラス内のすべての子アイテムを削除しようとしています。
モデル:
public class Ticket
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public virtual ICollection<TicketItem> TicketItems { get; set; }
public Ticket()
{
TicketItems = new List<TicketItem>();
}
}
public class TicketItem
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
[DataType(DataType.Currency)]
[DisplayFormat(DataFormatString = "{0:C}")]
public double Price { get; set; }
public int TicketId { get; set; }
public virtual Ticket Ticket { get; set; }
}
コントローラ:
[HttpPost]
public ActionResult Edit(TicketViewModel ticketViewModel)
{
if (ModelState.IsValid)
{
var ticket = ticketViewModel.Ticket;
context.Entry(ticket).State = EntityState.Modified;
context.Entry(ticket).Collection(i => i.TicketItems).Load();
ticket.TicketItems.Clear();
context.SaveChanges();
AddOrUpdateItems(ticket, ticketViewModel.Items);
return RedirectToAction("Index");
}
return View(ticketViewModel);
}
private void AddOrUpdateItems(Ticket ticket, ICollection<AssignedItem> assignedItems)
{
foreach (var assignedItem in assignedItems)
{
if (assignedItem.Assigned)
{
var item = context.Items.Find(assignedItem.Id);
var ticketItem = CreateTicketItem(item, ticket);
ticket.TicketItems.Add(ticketItem);
}
}
}
モデルビルダーに以下を追加しようとしました:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
...
modelBuilder.Entity<Ticket>()
.HasMany(t => t.TicketItems)
.WithRequired(i => i.Ticket)
.WillCascadeOnDelete();
...
}
コントローラーで edit メソッドを使用すると、次のエラーが発生します。
操作に失敗しました: 1 つ以上の外部キー プロパティが null 非許容であるため、リレーションシップを変更できませんでした。リレーションシップに変更が加えられると、関連する外部キー プロパティが null 値に設定されます。外部キーが null 値をサポートしていない場合は、新しい関係を定義するか、外部キー プロパティに別の非 null 値を割り当てるか、関連のないオブジェクトを削除する必要があります。
これはデータベースの FK 制約に関連していることを知っています。すべての子エントリが削除WillCascadeOnDelete()
されるため、これを追加することで問題が解決すると思いました。Clear()