私は一日のようにこれによって挫折しました...助けてください。ASP.NET MVC 3 EF CodeFirst - DBContextアイテムの編集
私は、JQueryを使用してDOM要素を追加/削除することで新しい項目を動的に追加できる請求書セクションを持っています...これらの要素の名前を正しく指定する方法はすでにわかっていますモデルを作成し、アクションパラメータに送信します。
それでは、私は種類の請求書のPARAM
[HttpPost]
public virtual ActionResult Edit(Invoice invoice) {
if (ModelState.IsValid) {
//code discussed below
}
return RedirectToAction("Index");
}
と編集請求書のパラメータは、私がしたいすべてのデータが含まれていると呼ばれる私のコントローラ内のアクションを持っているとしましょう。私はこれに問題はありません。以下はオブジェクトモデルです。
public class Invoice
{
[Key]
public int ID { get; set; }
public InvoiceType InvoiceType { get; set; }
public string Description { get; set; }
public int Amount { get; set; }
public virtual ICollection<InvoiceItem> InvoiceItems { get; set; }
}
InvoiceItemsコレクションに注意してください - これは、動的に挿入された請求書の項目のコレクションが含まれています。 InvoiceItemモデルは以下の通りです
[Table("InvoiceItems")]
public class InvoiceItem
{
[Key]
public int ID { get; set; }
[ForeignKey("Invoice")]
public int InvoiceID { get; set; }
public Invoice Invoice { get; set; }
public string Description { get; set; }
public int Amount { get; set; }
}
そして、それが私が立ち往生しているところです。
私はインボイスコレクションInvoiceItems内の項目を間違いなくデータベースに挿入/更新できません。私はたくさんの検索を行っていますが、これらの解決策を見つけました。残念ながら、これらの解決策はありません。
溶液#1 - SetValuesといくつかの奇妙なコード:
Invoice origInvoice = db.Invoices.Single(x => x.ID == invoice.ID);
var entry = db.Entry(origInvoice);
entry.OriginalValues.SetValues(invoice);
entry.CurrentValues.SetValues(invoice);
db.SaveChanges();
溶液#2 - 私のDbContextに新しいupdateメソッドを追加:
public void Update<T>(T entity) where T : class
{
this.Set<T>().Attach(entity);
base.ObjectContext.ObjectStateManager.ChangeObjectState(entity,System.Data.EntityState.Modified);
}
溶液#3 - 存在するが変更されたエンティティを文脈に付けること。http://blogs.msdn.com/b/adonet/archive/2011/01/29/using-dbcontext-in-ef-feature-ctp5-part-4-add-attach-and-entity-states.aspx
db.Entry(invoice).State = EntityState.Modified;
db.SaveChanges();
どう溶液#1作品:が新しく追加されたInvoiceItems以外のすべてのプロパティを更新します。 SetValues()はICollectionプロパティを無視します。これは、db.SaveChanges()の直前にこの行を追加した場合に機能します。
origEntry.Entity.InvoiceItems = invoice.InvoiceItems;
...しかし、これは正しいアプローチではないと私は信じています。
解決方法2:は、DbContextクラスにObjectContextプロパティがないため、まったく機能しません。
解決方法3:このソリューションは請求書を更新しますが、それ以外の場合はInvoiceItemsを無視します。
追加情報:以下は、InvoiceItemプロパティにマップされるアイテム要素を生成するために使用されるjavascriptです。
window.InvoiceItemIndex++;
var str = $.tmpl("itemRowTmpl", {
itemIndexes: '<input type="hidden" name="Invoice.InvoiceItems.Index" value="' + window.InvoiceItemIndex + '"/> \
<input type="hidden" name="Invoice.InvoiceItems[' + window.InvoiceItemIndex + '].ID" value="0"/>\
<input type="hidden" name="Invoice.InvoiceItems[' + window.InvoiceItemIndex + '].InvoiceID" value="@Model.Invoice.ID"/>',
itemDescription: '<textarea cols="150" name="Invoice.InvoiceItems[' + window.InvoiceItemIndex + '].Description" rows="2"></textarea>',
itemAmount: '<input type="text" class="InvoiceItemAmount" style="text-align:right;" name="Invoice.InvoiceItems[' + window.InvoiceItemIndex + '].Amount" />',
});
最終的な質問:私は間違っていますか?データベースに自動的に挿入された別のモデルに関連して新しいアイテムのコレクションを持っているのは間違っていますか?親モデルが正常に更新されたとき、なぜ無視されますか?
編集1:修正
"アイテムを追加できません"と言うと、それはどういう意味ですか?例外が生成されたことを意味しますか?もしそうなら、例外は何ですか? –
はい、例外を掲示してください。 – Jack