Сначала обновите одно свойство записи в коде Entity Framework - PullRequest
17 голосов
/ 06 апреля 2011

Как я могу обновить одно свойство записи, не извлекая ее сначала?Я спрашиваю в контексте EF Code First 4.1

Говорит, что у меня есть класс User, сопоставление с таблицей Users в базе данных:

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

Теперь я хочуобновить LastActivity пользователя.У меня есть идентификатор пользователя.Я легко могу сделать это, запросив запись пользователя, установить новое значение LastActivity, а затем вызвать SaveChanges ().Но это приведет к избыточному запросу.

Я работаю, используя метод Attach.Но поскольку EF генерирует исключительную ситуацию проверки на Name, если оно равно null, я устанавливаю Name в произвольную строку (не будет обновляться обратно в DB).Но это не кажется элегантным решением:

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();
}

Я был бы очень признателен, если бы кто-то мог предоставить мне лучшее решение.И простите меня за любую ошибку, так как я впервые задаю вопрос по SO.

Ответы [ 3 ]

36 голосов
/ 07 апреля 2011

Это проблема реализации валидации.Валидация может валидировать только всю сущность.Он не проверяет только измененные свойства, как ожидалось.По этой причине проверка должна быть отключена в сценариях, где вы хотите использовать неполные фиктивные объекты:

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();
}

Это, очевидно, проблема, если вы хотите использовать один и тот же контекст для обновления фиктивных объектов и для обновленияцелых объектов, где проверка должна быть использована.Проверка происходит в SaveChanges, поэтому вы не можете сказать, какие объекты должны быть проверены, а какие нет.

4 голосов
/ 18 июля 2013

Я на самом деле имею дело с этим прямо сейчас.Я решил переопределить метод ValidateEntity в контексте БД.

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);
} 

Я уверен, что в нем есть некоторые дыры, но он кажется лучше, чем альтернативы.

3 голосов
/ 06 апреля 2011

Вы можете попробовать что-то вроде взлома:
context.Database.ExecuteSqlCommand("update [dbo].[Users] set [LastActivity] = @p1 where [Id] = @p2",<br> new System.Data.SqlClient.SqlParameter("p1", DateTime.Now),<br> new System.Data.SqlClient.SqlParameter("p2", id));

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...