SaveChanges () не изменяет существующую запись базы данных с обновленными данными - PullRequest
0 голосов
/ 14 февраля 2019

Я пытаюсь обновить существующую запись в моей базе данных SQL, вызывая _dbContext.SaveChanges (), но она не обновляет запись новым изменяемым значением.

Я пробовал все другие решения, которые ямог найти со ссылкой на мою проблему, но ни один из них не работал.

Мой код выглядит следующим образом:

public int UpdateRank(Guid localId, int rank, Guid entityTypeId)
{            
    var result = _dbContext.EntityAttribute.FirstOrDefault(en => en.ParentGuid == localId && en.EntityAttributeTypeId == entityTypeId);
        result.IntValue = rank;
        return _dbContext.SaveChanges();            
    }

После нахождения нескольких решений я также попытался добавить

_dbContext.Entry(result).State = EntityState.Modified;

Как и

_dbContext.EntityAttribute.Attach(result);

перед _dbContext.SaveChanges () безрезультатно.

Если у меня есть какая-либо из предыдущих последовательностей кода из этих фрагментов, предшествующих _dbContext.SaveChanges (), код выполняется и не выдает ошибку, но не обновляет запись.Если я добавлю

_dbContext.EntityAttribute.Update(result);

и затем вызову SaveChanges, я получу следующую ошибку: SqlException: не удается обновить столбец идентификатора 'ID'.

Где ID - это сгенерированный базой bigint.Я добавил оба

_dbContext.EntityAttribute.Update(result).Property(en => en.Id).IsModified = false;
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]

в метод UpdateRank и в файл базы данных EntityAttribute в моем проекте доступа к данным соответственно, и они сделали код работающим без ошибок, но запись все еще не обновлялась после вызова SaveChanges.

Когда я отлаживаю код, я вижу, что свойство IntValue для результата имеет первое введенное мной значение (4) каждый раз, когда его получают, поэтому кажется, что dbContext удерживает объект результата.Это просто не обновляет мою базу данных с измененным значением.Моя база данных также является удаленной базой данных, она не размещена на моей локальной машине.Я не смог найти ничего, что могло бы быть проблемой.

Буду признателен за любую помощь.

1 Ответ

0 голосов
/ 14 февраля 2019

Вероятно, вам потребуется добавить более подробную информацию к вашему вопросу, включая определение сущности и / или конфигурацию типа сущности EF для EntityAttribute, включая любые атрибуты для сопоставления.Является ли IntValue сопоставленным как FK другому объекту?Это наиболее вероятная причина того, что вы не видите обновлений.

Например, если EntityAttribute выглядит примерно так:

public class EntityAttribute
{
   // ... properties, key, etc.

   public int IntValue { get; set; }

   [ForeignKey("IntValue")]
   public virtual IntAttribute MyInt { get; set; }
}

Тогда вы сталкиваетесь с ситуацией, когда есть два способа указать EntityAttributeна новом экземпляре IntAttribute, и немного сценария курица и яйцо.Если запись начинает IntValue с 4 и MyInt с идентификатором 4, это может означать изменение ее на «5», так как либо установите IntValue на 5, либо установите MyInt для объекта с ID = 5. Второй вариант является правильным, когдау вас есть определенный столбец FK:

public int UpdateRank(Guid localId, int rank, Guid entityTypeId)
{            
    var result = _dbContext.EntityAttribute.Single(en => en.ParentGuid == localId 
        && en.EntityAttributeTypeId == entityTypeId);
    var myInt = _dbContext.MyInts.Single(x => x.MyIntId == rank);
    result.MyInt = myInt;
    return _dbContext.SaveChanges();            
}

Это предполагает, что FK указывает на ссылочное свойство с именем "MyInt" с сущностью DbSet с именем MyInts.Принятие правильного соглашения об именовании в ваших сущностях для идентификаторов (PK и FK) значительно облегчит понимание вашего кода.

Примечание. Я изменил FirstOrDefault на Single.С Linq используйте наиболее ограниченную ожидаемую операцию.Используйте «OrDefault» только в том случае, если вы ожидаете, что строки должны быть доступны или нет, и обрабатываете сценарий, в котором они отсутствуют.Если вы ожидаете 1 строку, используйте «Single», а не «First».«Первое» означает, что я ожидаю многих, но только о первом, и оно всегда должно включать в себя предложение OrderBy.Это сделано для того, чтобы избежать потенциальных ошибок (обновление неправильной записи, появление исключений NullReference и т. Д.)

Теперь, если вы уверены, что нет ссылки на FK, попробуйте следующее:

public int UpdateRank(Guid localId, int rank, Guid entityTypeId)
{            
    var result = _dbContext.EntityAttribute.Single(en => en.ParentGuid == localId 
         && en.EntityAttributeTypeId == entityTypeId);
    result.IntValue = rank;
    return _dbContext.SaveChanges();            

    var test = result.IntValue;
}

Установите точку останова на линии var test = ....Какое значение возвращается в test?Если исходное значение IntValue равно «4», rank равно «5», а test возвращается как «4», то определенно происходит что-то странное.Если test возвращается как «5», то база данных в этот момент также должна сообщить «5», и, вероятно, что-то еще сбрасывает значение.С точкой останова в этой строке «test =» после SaveChanges проверьте базу данных с помощью ручного запроса.Если запрос не может быть запущен с включенной точкой останова, то другим подозрением может быть то, что вы работаете в открытой транзакции, и транзакция не фиксируется после этого вызова.Открытая транзакция блокирует выполнение запроса до тех пор, пока область Tx не будет завершена.Для транзакций стандартным действием является откат любых изменений, если не указано зафиксировать.Если он не заблокирован, а в БД отображается «4», но test показывает «5», я бы внимательно посмотрел, чтобы убедиться, что вы используете Single, а не FirstOrDefault, потому что это будет выглядеть как ошибка, когдавы запрашиваете одну запись в БД, а EF выбирает другую.(т. е. вы ожидаете 1 запись, но есть несколько, которые соответствуют критериям.) Использование Single вызовет исключение в этом случае, в результате будет получена 1 запись, но возвращено несколько.

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