Я был разочарован этим как день ... пожалуйста help.
У меня есть раздел счетов-фактур, в котором я могу динамически добавлять новые элементы, добавляя / удаляя элементы DOM с помощью JQuery ... Я уже понял, как правильно называть эти элементы, чтобы они соответственно и правильно отображались в модель и отправить в параметр действия.
Итак, допустим, у меня есть действие в моем контроллере под названием Edit с параметром типа Invoice
[HttpPost]
public virtual ActionResult Edit(Invoice invoice) {
if (ModelState.IsValid) {
//code discussed below
}
return RedirectToAction("Index");
}
Параметр invoice содержит все данные, которые мне нужны. У меня нет проблем с этим. Ниже представлена объектная модель.
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 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 в базе данных. Я много искал в Google и нашел эти решения - ни одно из них, к сожалению, не работает.
Решение №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:
public void Update(T entity) where T : class
{
this.Set().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.
Дополнительная информация: ниже приведен фрагмент javascript, который используется для создания элементов элемента, сопоставленных со свойствами InvoiceItem.
window.InvoiceItemIndex++;
var str = $.tmpl("itemRowTmpl", {
itemIndexes: ' \
\
',
itemDescription: '',
itemAmount: '',
});
Последний вопрос: что я делаю не так? Что плохого в том, что новая коллекция элементов по отношению к другой модели автоматически вставляется в базу данных? Почему он игнорируется, когда родительская модель обновляется успешно?
Редактировать 1: исправления