Я был разочарован этим как день ... пожалуйста, помогите.
У меня есть раздел счетов, в котором я могу динамически добавлять новые элементы, добавляя / удаляя элементы DOM с помощью JQuery...я уже выяснила, как правильно называть эти элементы, чтобы они соответственно и правильно отображались в модели и отправлялись в параметр действия.
Итак, допустим, у меня в контроллере есть действие, которое называется Edit with paramтипа 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<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 коллекции Invoice в базу данных случайно.Я много гуглял и нашел эти решения - к сожалению, ни одно из них не работает.
Решение # 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>(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.
Дополнительная информация: следующим является фрагмент javascript, который используется для создания элементов элемента, которые сопоставлены со свойствами InvoiceItem.Последний вопрос: что я делаю не так?Что плохого в том, чтобы новая коллекция предметов относительно другой модели автоматически вставлялась в базу данных?Почему это игнорируется, когда родительская модель успешно обновляется?
Редактировать 1: исправления