How to update not every fields of an object using Entity Framework and EntityState.Modified

前端 未结 5 1329
鱼传尺愫
鱼传尺愫 2020-12-02 10:49

I need to update all fields except property1 and property2 for the given entity object.
Having this code:

    [HttpPost]
    public ActionResult Add(ob         


        
相关标签:
5条回答
  • 2020-12-02 11:14

    The answers above (most of them) use DbContext. For those who is using ObjectContext these solutions arent accessible.

    Here is solution for ObjectContext strictly (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");
    
    0 讨论(0)
  • 2020-12-02 11:16

    This is an update that works for .net CORE and maybe can help someone who needs a generic solucion and wants to exclude some properties base on different conditions.

    I'm using reflection to iterate through the properties and update base on its property value, in this case, as example, i'm excluding the null properties.

        public virtual TEntity Update(TEntity entity)
        {
            dbSet.Attach(entity);
            dbContext.Entry(entity).State = EntityState.Modified;
    
            var entry = dbContext.Entry(entity);
    
            Type type = typeof(TEntity);
            PropertyInfo[] properties = type.GetProperties();
            foreach (PropertyInfo property in properties)
            {
                if (property.GetValue(entity, null) == null)
                {
                    entry.Property(property.Name).IsModified = false;
                }
            }
    
            dbContext.SaveChanges();
            return entity;
        }
    
    0 讨论(0)
  • 2020-12-02 11:22

    This question was already nicely answered, but I wanted to provide an extension method for anyone who would like to use it.

    This code was developed for 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();
    }
    

    Usage Example

    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
    }
    
    0 讨论(0)
  • 2020-12-02 11:23

    Let's assume that you have a collection of the properties to be excluded:

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

    With EF5 on .NET 4.5 you can do this:

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

    This uses a new feature of EF5 on .NET 4.5 which allows a property to be set as not modified even after it has been previously set to modified.

    When using EF 4.3.1 or EF5 on .NET 4 you can do this instead:

    var entry = context.Entry(obj);
    foreach (var name in entry.CurrentValues.PropertyNames.Except(excluded))
    {
        entry.Property(name).IsModified = true;
    }
    
    0 讨论(0)
  • 2020-12-02 11:25

    You can't define such an exception. You can however mark single properties as modified:

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

    Note that setting IsModified to false is not supported once you have marked the state of the whole entity to Modified.

    For your purpose I would actually prefer to load the entity from the database and then update it using normal change tracking:

    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();
    
    0 讨论(0)
提交回复
热议问题