Join to update Entity Framework

I am trying to do an update for a table using EF 5.x using attach. other fields are required in this table, but this is an existing row. so I'm trying to update without any fetch. userid is the primary key for the table. I am trying to update the status. but it generates an EntityValidationErrors that requires a password, which is another required field but not a primary key. since this is updating an existing row, why do you need to provide updated fields for updating?

var webUser = new WebUser() { UserId = webUserId, OnlineStatus = (sbyte)status }; using (var dbxupdate = new xEntities()) { try { dbxupdate.WebUsers.Attach(webUser); dbxupdate.Entry(webUser).State = EntityState.Modified; dbxupdate.Entry(webUser).Property(x => x.OnlineStatus).IsModified = true; dbxupdate.SaveChanges(); } catch (DbEntityValidationException dbEx) { foreach (var validationErrors in dbEx.EntityValidationErrors) { foreach (var validationError in validationErrors.ValidationErrors) { Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage); } } } } 
+6
source share
4 answers

In an entity infrastructure, you cannot update a field without setting appropriate values ​​for other fields. therefore, it is better to use the stored procedure for your work. And another way is to fetch the record and then update the field.

+1
source

.Attach() really only useful for updating objects in a separate script like this:

 User entity = null; using (var db = new DbContext()) { entity = (from p in db.Users where p.id == 1 select p).FirstOrDefault(); System.Diagnostics.Trace.WriteLine(entity.Name); //Outputs "Jane Doe" } entity.Name = "John Doe" //Modified while no longer connected to database using (var db = new DbContext()) { db.Users.Attach(entity); db.Entry(entity).Property(a => a.Name).IsModified = true; db.SaveChanges(); System.Diagnostics.Trace.WriteLine(entity.Name); //Now outputs "John Doe" } 

In your scenario, the object you are creating is not retrieved by this key, and the database considers it as a completely new entity. I assume that your password is a non-zero field, and therefore EF throws an error when trying to save your changes. If you did not have such errors, EF would automatically delete any fields that you did not modify, and then save the object (which is not the result you are looking for).

To make the changes you are looking for, you probably have to do something like the following:

 using (var db = new DbContext()) { db.Users.Single(a => a.id == 1).OnlineStatus = (sbyte)status; db.SaveChanges } 

And then add any other error handling / checking code you want. Alternatively, you can save the object in a variable to make changes to more than one field at a time. EF should automatically detect which values ​​have been changed, and only generate the SQL necessary to make those changes. This means that if you have something like:

 foreach (var item in entityList) { var entity = db.Users.Single(a => a.id == item.id); entity.Name = item.Name; entity.Address = item.Address; } 

Someone will correct me if I am wrong, but EF should only update entities / fields that this code really affects. If the name or address remains the same, EF will skip this field for this object when it saves the changes to the database.

+15
source

An entity is checked when it is saved, regardless of whether it was attached or loaded from the database. If you use validation attributes or a validation method, the object must pass validation to save.

If you have the [Required] attribute in the password field, I think you're completely stuck. You may have to download the object and then update the information, rather than just attaching it.

+2
source

try this: replace the first line (put this inside the using statement)
var wu = dbxupdate.webUsers.single(i=>i.id== webUserId);
wu.OnlineStatus = whatever;

the code continues ... to update the object, you must get an instance of it. otherwise, you create a new one where properties that are not declared get null .

0
source

All Articles