Me he sentido frustrado por esto como un día ... por favor ayuda.ASP.NET MVC 3 EF CodeFirst - DBContext artículo de edición
Tengo una sección de factura en la que puedo agregar nuevos elementos dinámicamente agregando/eliminando elementos DOM usando JQuery ... ya he descubierto cómo nombrar estos elementos correctamente para que se asignen en consecuencia y correctamente a el modelo y enviar al parámetro de acción.
Así que vamos a decir que tengo una acción en mi controlador llamado Editar con el parámetro de tipo de factura
[HttpPost]
public virtual ActionResult Edit(Invoice invoice) {
if (ModelState.IsValid) {
//code discussed below
}
return RedirectToAction("Index");
}
El parámetro factura contiene todos los datos que quiero. No tengo un problema con esto El siguiente es el modelo de objeto.
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; }
}
Nota del InvoiceItems colección - contiene una colección de las posiciones de factura insertados de forma dinámica. El siguiente es el modelo 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; }
}
Y ahí es donde estoy atascado.
No puedo insertar/actualizar los elementos en Factura de la colección InvoiceItems en la base de datos por casualidad. He estado buscando en Google y he encontrado estas soluciones, lamentablemente ninguno de estos funciona.
Solución # 1 - un código extraño con 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();
Solución # 2 - la adición de un nuevo método de actualización a mi DbContext:
public void Update<T>(T entity) where T : class
{
this.Set<T>().Attach(entity);
base.ObjectContext.ObjectStateManager.ChangeObjectState(entity,System.Data.EntityState.Modified);
}
Solución # 3 - asociar una entidad existente pero modificada al contexto de acuerdo con 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();
Cómo la solución # 1 obras: actualiza todas las propiedades excepto InvoiceItems recién añadidos. SetValues () ignora la propiedad ICollection. Esto funcionaría si añadiera esta línea justo antes de db.SaveChanges();
origEntry.Entity.InvoiceItems = invoice.InvoiceItems;
... pero no creo que este sea el enfoque correcto en absoluto.
Cómo funciona la solución n. ° 2: no funciona en absoluto porque no hay ninguna propiedad ObjectContext en la clase DbContext.
Cómo funciona la solución n. ° 3: esta solución actualizará la factura pero, de lo contrario, ignorará InvoiceItems.
información adicional: siguiente es la pieza de javascript que se utiliza para generar los elementos artículo que se asignan a las propiedades InvoiceItem.
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" />',
});
La última pregunta: ¿qué estoy haciendo mal? ¿Qué hay de malo en tener una nueva colección de artículos en relación con otro modelo que se inserta automáticamente en la base de datos? ¿Por qué se ignora cuando el modelo principal se actualiza con éxito?
Editar 1: correcciones
Cuando dices que "no puedes agregar los elementos", ¿qué significa eso exactamente? ¿Significa que se genera una excepción? Si es así, ¿cuál es la excepción? –
Sí, ¿puede por favor publicar la excepción? – Jack