only Update a single property of a record in Entity Framework Code First




how to update record using entity framework in c# (3)

How can I update a single property of a record without retrieving it first? I'm asking in the context of EF Code First 4.1

Says I have a class User, mapping to table Users in Database:

class User
{
    public int Id {get;set;}
    [Required]
    public string Name {get;set;}
    public DateTime LastActivity {get;set;}
    ...
}

Now I want to update LastActivity of a user. I have user id. I can easily do so by querying the user record, set new value to LastActivity, then call SaveChanges(). But this would result in a redundant query.

I work around by using Attach method. But because EF throws a validation exception on Name if it's null, I set Name to a random string (will not be updated back to DB). But this doesn't seem a elegant solution:

using (var entities = new MyEntities())
{
    User u = new User {Id = id, Name="this wont be updated" };
    entities.Users.Attach(u);
    u.LastActivity = DateTime.Now;
    entities.SaveChanges();
}

I would be very appriciate if someone can provide me a better solution. And forgive me for any mistake as this is the first time I've asked a question on SO.


This is a problem of validation implementation. The validation is able to validate only a whole entity. It doesn't validate only modified properties as expected. Because of that the validation should be turned off in scenarios where you want to use incomplete dummy objects:

using (var entities = new MyEntities())
{
    entities.Configuration.ValidateOnSaveEnabled = false;

    User u = new User {Id = id, LastActivity = DateTime.Now };
    entities.Users.Attach(u);
    entities.Entry(user).Property(u => u.LastActivity).IsModified = true;
    entities.SaveChanges();
}

This is obviously a problem if you want to use the same context for update of dummy objects and for update of whole entities where the validation should be used. The validation take place in SaveChanges so you can't say which objects should be validated and which don't.


You can try a sort of hack:
context.Database.ExecuteSqlCommand("update [dbo].[Users] set [LastActivity] = @p1 where [Id] = @p2",
new System.Data.SqlClient.SqlParameter("p1", DateTime.Now),
new System.Data.SqlClient.SqlParameter("p2", id));


I'm actually dealing with this right now. What I decided to do was override the ValidateEntity method in the DB context.

protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items)
{
    var result = base.ValidateEntity(entityEntry, items);

    var errors = new List<DbValidationError>();

    foreach (var error in result.ValidationErrors)
    {
        if (entityEntry.Property(error.PropertyName).IsModified)
        {
            errors.Add(error);
        }
    }

    return new DbEntityValidationResult(entityEntry, errors);
} 

I'm sure there's some holes that can be poked in it, but it seemed better than the alternatives.







entity-framework-4.1