entity-framework entity-framework-4.1

Cómo actualizar no todos los campos de un objeto utilizando Entity Framework y EntityState.Modified



entity-framework entity-framework-4.1 (4)

Esta pregunta ya estaba bien respondida, pero quería proporcionar un método de extensión para cualquiera que quisiera usarla.

Este código fue desarrollado para EF 4.3.1

//You will need to import/use these namespaces using System.Data.Entity; using System.Data.Entity.Infrastructure; //Update an entity object''s specified columns, comma separated //This method assumes you already have a context open/initialized public static void Update<T>(this DbContext context, T entityObject, params string[] properties) where T : class { context.Set<T>().Attach(entityObject); var entry = context.Entry(entityObject); foreach(string name in properties) entry.Property(name).IsModified = true; context.SaveChanges(); }

Ejemplo de uso

using (FooEntities context = new FooEntities()) { FooEntity ef = new FooEntity(); //For argument''s sake say this entity has 4 columns: // FooID (PK), BarID (FK), Name, Age, CreatedBy, CreatedOn //Mock changes ef.FooID = 1; ef.Name = "Billy"; ef.Age = 85; context.Update<FooEntity>(ef, "Name", "Age"); //I only want to update Name and Age }

Necesito actualizar todos los campos excepto property1 y property2 para el objeto de entidad dado.
Teniendo este código:

[HttpPost] public ActionResult Add(object obj) { if (ModelState.IsValid) { context.Entry(obj).State = System.Data.EntityState.Modified; context.SaveChanges(); } return View(obj); }

¿Cómo cambiarlo para agregar una excepción a obj.property1 y obj.property2 por no actualizarse con este código?


Las respuestas anteriores (la mayoría de ellas) usan DbContext. Para aquellos que usan ObjectContext estas soluciones no son accesibles.

Aquí hay una solución para ObjectContext estrictamente ( EF5 .NET 4.5 ):

ctx.AddObject("ENTITYNAME", item); ctx.ObjectStateManager.ChangeObjectState(item, EntityState.Modified); var entry = ctx.ObjectStateManager.GetObjectStateEntry(item); entry.RejectPropertyChanges("PROPERTY_TO_EXCLUDE");


No puedes definir tal excepción. Sin embargo, puede marcar propiedades individuales como modificadas:

context.Entry(obj).Property(o => o.Property3).IsModified = true; context.Entry(obj).Property(o => o.Property4).IsModified = true; // etc.

Tenga en cuenta que la configuración de IsModified en false no se admite una vez que haya marcado el estado de la entidad completa en Modified .

Para su propósito, preferiría cargar la entidad desde la base de datos y luego actualizarla usando el seguimiento de cambio normal:

var objInDB = context.Objects.Single(o => o.Id == obj.Id); obj.Property1 = objInDB.Property1; obj.Property2 = objInDB.Property2; context.Entry(objInDB).CurrentValues.SetValues(obj); context.SaveChanges();


Supongamos que tiene una colección de las propiedades que se excluirán:

var excluded = new[] { "property1", "property2" };

Con EF5 en .NET 4.5 puede hacer esto:

var entry = context.Entry(obj); entry.State = EntityState.Modified; foreach (var name in excluded) { entry.Property(name).IsModified = false; }

Esto utiliza una nueva característica de EF5 en .NET 4.5 que permite que una propiedad se configure como no modificada incluso después de haber sido configurada previamente para ser modificada.

Cuando use EF 4.3.1 o EF5 en .NET 4 puede hacer esto en su lugar:

var entry = context.Entry(obj); foreach (var name in entry.CurrentValues.PropertyNames.Except(excluded)) { entry.Property(name).IsModified = true; }