J'ai besoin de mettre à jour tous les champs sauf property1 et property2 pour l'objet entité donné.
Avoir ce code:
[HttpPost]
public ActionResult Add(object obj)
{
if (ModelState.IsValid)
{
context.Entry(obj).State = System.Data.EntityState.Modified;
context.SaveChanges();
}
return View(obj);
}
Comment le changer pour ajouter une exception à obj.property1 et obj.property2 pour ne pas être mis à jour avec ce code?
Supposons que vous ayez une collection de propriétés à exclure:
var excluded = new[] { "property1", "property2" };
Avec EF5 sur .NET 4.5, vous pouvez le faire:
var entry = context.Entry(obj);
entry.State = EntityState.Modified;
foreach (var name in excluded)
{
entry.Property(name).IsModified = false;
}
Cela utilise une nouvelle fonctionnalité d'EF5 sur .NET 4.5 qui permet de définir une propriété comme non modifiée même après qu'elle ait été précédemment définie comme modifiée.
Lorsque vous utilisez EF 4.3.1 ou EF5 sur .NET 4, vous pouvez le faire à la place:
var entry = context.Entry(obj);
foreach (var name in entry.CurrentValues.PropertyNames.Except(excluded))
{
entry.Property(name).IsModified = true;
}
Vous ne pouvez pas définir une telle exception. Vous pouvez cependant marquer des propriétés uniques comme modifiées:
context.Entry(obj).Property(o => o.Property3).IsModified = true;
context.Entry(obj).Property(o => o.Property4).IsModified = true;
// etc.
Notez que la définition de IsModified
sur false
n'est pas prise en charge une fois que vous avez marqué l'état de l'entité entière sur Modified
.
Pour votre objectif, je préférerais en fait charger l'entité à partir de la base de données, puis la mettre à jour en utilisant le suivi des modifications 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();
Cette question a déjà été bien répondu, mais je voulais fournir une méthode d'extension pour tous ceux qui souhaitent l'utiliser.
Ce code a été développé pour 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();
}
Exemple d'utilisation
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
}
Les réponses ci-dessus (la plupart d'entre elles) utilisent DbContext. Pour ceux qui utilisent ObjectContext, ces solutions ne sont pas accessibles.
Voici une solution pour ObjectContext strictement ( 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");