Объект не обновляется с использованием подхода Code-First - PullRequest
1 голос
/ 25 мая 2019

У меня есть этот класс, который я использую для операций с БД:

public class EntityService<TEntity> : IRepository<TEntity> where TEntity : BaseModel
{

     ApplicationDbContext _context;
     private DbSet<TEntity> _entities;

     public EntityService()
     {
         _context = new ApplicationDbContext();
     }

     public virtual void Update(TEntity entity)
     {
          if (entity == null)
               throw new ArgumentNullException(nameof(entity));

          try
          {
                var dbEnt = _context.Set<TEntity>().Where(c => c.Id == entity.Id).First();

                dbEnt = entity;
                dbEnt.UpdatedBy = GetCurrentUser();
                dbEnt.DateUpdated = DateTime.Now;
                _context.SaveChanges();
           }
           catch (DbUpdateException exception)
           {
                throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception);
           }

           //-----other methods for insert and get working fine----
}

В этом классе есть и другие методы для insert и get, которые работают нормально.Только этот метод обновления не обновляет сущность и не выдает исключение.

ОБНОВЛЕНИЕ

Я сталкиваюсь с подобной проблемой, но при работе здесь все наоборот: Метод Add (), добавляющий дублирующиеся строки для связанных моделей в Code-First Entity Framework

Я думаю, что эти два имеют одну и ту же причину отслеживания изменений.Но один добавляет другой, а не обновляет.

Ответы [ 4 ]

4 голосов
/ 26 мая 2019

Строка ...

var dbEnt = _context.Set<TEntity>().Where(c => c.Id == entity.Id).First();

... присоединяет объект сущности к контексту и возвращает ссылку на эту сущность.

Затем строка ...

dbEnt = entity;

... заменяет эту ссылку ссылкой на переменную entity, которая входит в метод.То есть не отслеживаемый объект сущности .Вы в основном потеряли ссылку на отслеживаемую сущность, и ее невозможно больше изменить.

Вы должны либо присоединить entity к контексту и пометить его как измененный, либо получить dbEnt, как вы уже сделали, иизменить и сохранить этот объект.Оба метода имеют свои плюсы и минусы, см. здесь .

1 голос
/ 04 июня 2019

После получения объекта из _context обновите все поля из новой детализации и установите для состояния объекта измененное значение

var dbEnt = _context.Set<TEntity>().Where(c => c.Id == entity.Id).First();
dbEnt.Name = entity.Name;
...
...
...
dbEnt.UpdatedBy = GetCurrentUser();
dbEnt.DateUpdated = DateTime.Now;
_context.Entry(dbEnt).State = EntityState.Modified;
_context.SaveChanges();
0 голосов
/ 05 июня 2019

Спасибо всем.Я получил много подсказок из ваших ответов.Как подсказали мне @GertArnold и @Colonel Software, я изменил свой код следующим образом, и он заработал:

//Assigning BaseModel properties
entity.CreatedBy = dbEnt.CreatedBy;
entity.UpdatedBy = GetCurrentUser();
entity.DateUpdated = DateTime.Now;
entity.DateCreated = dbEnt.DateCreated;

//Changing entity states
_context.Entry(dbEnt).State = EntityState.Detached;
_context.Entry(entity).State = EntityState.Modified;

_context.SaveChanges();
0 голосов
/ 04 июня 2019

Если вы нашли свою сущность по идентификатору

var dbEnt = _context.Set<TEntity>().Where(c => c.Id == entity.Id).First();

, почему эта строка?

dbEnt = entity;

Удалите указанную выше строку, поскольку она удалит ссылку на отслеживаемый объект.

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