Attach for Update Entity Framework

ado.net c# entity-framework

Question

I am trying to do an update for a table using EF 5.x using attach. this table has other fields that are required but its an existing row. so i am trying to update without any fetch. userid is the primary key for the table. i am trying to update the status. but it throws an EntityValidationErrors saying password is required which is another required field but not primary key. since this is a update to existing row why do you need to provide the requried fields for update?

    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);
                }
            }
        }
    }
1
8
12/31/2012 8:14:02 PM

Accepted Answer

In entity framework, You can't update a field without setting appropriate values for other fields. so it is better to use a stored procedure for your job. And the other way is to fetch the record and then update the field.

1
3/24/2018 7:38:55 AM

Popular Answer

.Attach() is really only useful for updating entities in a detached scenario 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 entity you're creating isn't being retrieved by its key and the database is treating it as an entirely new entity. I assume that your password is a non-nullable field which then causes EF to throw an error when it attempts to save your changes. If you didn't have any such errors then EF would automatically null out any fields that you didn't modify and then save the entity (which isn't the result you're looking for either).

In order to make the changes that you really want, try something like the following:

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

And then add whatever other error handling/validation code that you want. Alternatively you could store the entity in variable for making changes to more than one field at a time. EF should automatically determine which values have been altered and only generate the SQL required to make those changes. Meaning that if you have something like:

using (var db = new DbContext()) {
    foreach (var item in entityList) {
        var entity = db.Users.Single(a => (a.Id == item.Id));

        entity.Name = item.Name;
        entity.Address = item.Address;
    }

    db.SaveChanges();
}

then EF should only update the entities/fields that are actually affected by this code. If the Name or Address stays the same then EF will skip that field for that entity when it saves the changes to the database.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow