Come aggiornare non tutti i campi di un object utilizzando Entity Framework ed EntityState.Modified

Devo aggiornare tutti i campi tranne property1 e property2 per l’object quadro dato.
Avere questo codice:

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

Come cambiarlo per aggiungere un’eccezione a obj.property1 e obj.property2 per non essere aggiornati con questo codice?

Supponiamo che tu abbia una collezione delle proprietà da escludere:

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

Con EF5 su .NET 4.5 puoi fare questo:

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

Questo utilizza una nuova funzionalità di EF5 su .NET 4.5 che consente di impostare una proprietà come non modificata anche dopo che è stata precedentemente modificata.

Se si utilizza EF 4.3.1 o EF5 su .NET 4, è ansible farlo invece:

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

Non è ansible definire tale eccezione. Puoi tuttavia contrassegnare singole proprietà come modificate:

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

Si noti che l’impostazione IsModified su false non è supportata dopo aver contrassegnato lo stato dell’intera entity framework su Modified .

Per il tuo scopo in realtà preferirei caricare l’entity framework dal database e quindi aggiornarla utilizzando il normale rilevamento delle modifiche:

 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(); 

Questa domanda aveva già una risposta soddisfacente, ma volevo fornire un metodo di estensione per chiunque volesse usarlo.

Questo codice è stato sviluppato per 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(this DbContext context, T entityObject, params string[] properties) where T : class { context.Set().Attach(entityObject); var entry = context.Entry(entityObject); foreach(string name in properties) entry.Property(name).IsModified = true; context.SaveChanges(); } 

Esempio di utilizzo

 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(ef, "Name", "Age"); //I only want to update Name and Age } 

Le risposte sopra (la maggior parte di esse) usano DbContext. Per coloro che utilizzano ObjectContext queste soluzioni non sono accessibili.

Ecco la soluzione per ObjectContext rigorosamente ( 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");