ASP.NET MVC 3 EF CodeFirst - редактирование элемента DBContext

Я был разочарован этим как день ... пожалуйста 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: исправления

8
задан Mirek 13 August 2011 в 11:53
поделиться

0 ответов

Другие вопросы по тегам:

Похожие вопросы: