Exclude property for upgrade in Entity framework

I was looking for a suitable way to mark a property that will NOT be changed when updating the model in MVC.

For example, take this small model:

class Model { [Key] public Guid Id {get; set;} public Guid Token {get; set;} //... lots of properties here ... } 

then the way to edit MVC is as follows:

 [HttpPost] public ActionResult Edit(Model model) { if (ModelState.IsValid) { db.Entry(model).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } return View(model); } 

Now, if my view does not contain a token, it will be canceled through this edit.

I am looking for something like this:

 db.Entry(model).State = EntityState.Modified; db.Entry(model).Property(x => x.Token).State = PropertyState.Unmodified; db.SaveChanges(); 

The best way I've found is to be on and set all the properties that I want to turn on manually, but I really only want to say which ones should be excluded.

+71
c # asp.net-mvc entity-framework
Sep 30 '12 at 14:13
source share
5 answers

we can use this as

  db.Entry(model).State = EntityState.Modified; db.Entry(model).Property(x => x.Token).IsModified = false; db.SaveChanges(); 

it will update, but without the Token property

+127
Jul 10 '13 at 11:54 on
source share

Create a new model that will have a limited set of properties that you want to update.

those. if your object model:

 public class User { public int Id {get;set;} public string Name {get;set;} public bool Enabled {get;set;} } 

You can create a custom view model that allows the user to change the name, but not the Enabled flag:

 public class UserProfileModel { public int Id {get;set;} public string Name {get;set;} } 

If you want to update the database, follow these steps:

 YourUpdateMethod(UserProfileModel model) { using(YourContext ctx = new YourContext()) { User user = new User { Id = model.Id } ; /// stub model, only has Id ctx.Users.Attach(user); /// track your stub model ctx.Entry(user).CurrentValues.SetValues(model); /// reflection ctx.SaveChanges(); } } 

When you call this method, you will update the name, but the Enabled property will remain unchanged. I used simple models, but I think you will get an image of how to use it.

+8
Sep 30
source share

Anyone looking for how to achieve this on EF Core. This is basically the same, but your IsModified should be after adding the model to update.

 db.Update(model); db.Entry(model).Property(x => x.Token).IsModified = false; db.SaveChanges(); 
+3
Sep 05 '19 at 15:14
source share

I made an easy way to edit the properties of entities that I will share with you. this code will edit the properties of the name and family of the object:

  public void EditProfileInfo(ProfileInfo profileInfo) { using (var context = new TestContext()) { context.EditEntity(profileInfo, TypeOfEditEntityProperty.Take, nameof(profileInfo.Name), nameof(profileInfo.Family)); } } 

And this code will be ignored for editing the properties of the name and family of the object, as well as for editing other properties:

  public void EditProfileInfo(ProfileInfo profileInfo) { using (var context = new TestContext()) { context.EditEntity(profileInfo, TypeOfEditEntityProperty.Ignore, nameof(profileInfo.Name), nameof(profileInfo.Family)); } } 

Use this extension:

 public static void EditEntity<TEntity>(this DbContext context, TEntity entity, TypeOfEditEntityProperty typeOfEditEntityProperty, params string[] properties) where TEntity : class { var find = context.Set<TEntity>().Find(entity.GetType().GetProperty("Id").GetValue(entity, null)); if (find == null) throw new Exception("id not found in database"); if (typeOfEditEntityProperty == TypeOfEditEntityProperty.Ignore) { foreach (var item in entity.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.GetProperty)) { if (!item.CanRead || !item.CanWrite) continue; if (properties.Contains(item.Name)) continue; item.SetValue(find, item.GetValue(entity, null), null); } } else if (typeOfEditEntityProperty == TypeOfEditEntityProperty.Take) { foreach (var item in entity.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.GetProperty)) { if (!item.CanRead || !item.CanWrite) continue; if (!properties.Contains(item.Name)) continue; item.SetValue(find, item.GetValue(entity, null), null); } } else { foreach (var item in entity.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.GetProperty)) { if (!item.CanRead || !item.CanWrite) continue; item.SetValue(find, item.GetValue(entity, null), null); } } context.SaveChanges(); } public enum TypeOfEditEntityProperty { Ignore, Take } 
+2
Apr 08 '18 at 7:07
source share

I think you do not want the property to be changed only in some cases, because if you are not going to use it never in your application, just remove it from your model.

If you want to use it only in some scenarios and avoid its "nullification" in the above case, you can try:

  • Hide a parameter in a view using HiddenFor:

    @Html.HiddenFor(m => m.Token)

This will cause your original value to be saved unchanged and passed back to the controller.

Download your object in the controller again from your DBSet and run this method. You can specify both a white list and a black list of parameters that should or should not be updated.

+1
01 Oct
source share



All Articles