ASP.NET 5 EF 7 не может обновить запись в таблице базы данных

Я создаю API, который позволит функциям CRUD создавать, читать, обновлять и удалять записи в базе данных.

Я столкнулся с проблемой, которая не позволяет мне обновлять запись внутри таблицы из-за того, что экземпляр является общим, и я получаю сообщение об ошибке ниже.

cannot be tracked because another instance of this type with the same key is already being tracked. For new entities consider using an IIdentityGenerator to generate unique key values."

Вот мой код:

[HttpPut("{id}")]
        public JsonResult Put(int Id, [FromBody]PackageVersion updatePackage)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    if (updatePackage == null || updatePackage.Id != Id)
                    {
                        Response.StatusCode = (int)HttpStatusCode.BadRequest;
                        return Json(new { status = "Bad Request" });
                    }

                    var package = _respository.GetPackageById(Id);
                    if (package == null)
                    {
                        Response.StatusCode = (int)HttpStatusCode.NotFound;
                        return Json(new { status = "Not Found", Message = package });
                    }

                    _respository.UpdatePackage(updatePackage);
                    if (_respository.SaveAll())
                    {
                        Response.StatusCode = (int)HttpStatusCode.Accepted;
                        return Json(updatePackage);
                    }
                }
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return Json(new { status = "Failed", ModelState = ModelState });
            }
            catch (Exception ex)
            {
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return Json(new { status = "Failed", Message = ex.Message });
            }
        }

В приведенном выше коде вы заметите, что я сначала получаю запись, используя репозиторий _repository.GetPackageById(Id), что позволяет мне проверить, находится ли запись в базе данных, и я могу продолжить обновление, используя репозиторий _repository.UpdatePackage(updatePackage). Если я закомментирую нижеприведенный код в своем контроллере, я смогу сохранить данные в базе данных.

//var package = _respository.GetPackageById(Id);
//if (package == null)
//{
//    Response.StatusCode = (int)HttpStatusCode.NotFound;
//    return Json(new { status = "Not Found", Message = package });
//}

Я также убедился, что использую AddScoped в конфигурации запуска, как указано в этом нить.

services.AddScoped<IAutomationRepository, AutomationRepository>();

Я не уверен, почему я не могу использовать несколько экземпляров DBContext для одного и того же идентификатора при его вызове.

Любое предложение действительно ценится. :)

ОБНОВЛЕНИЕ 1:

public class AutomationRepository : IAutomationRepository
    {
        private AutomationDBContext _context;

        public AutomationRepository(AutomationDBContext context)
        {
            _context = context;
        }

        public void AddPackage(PackageVersion newPackage)
        {
            _context.Add(newPackage);
        }

        public void DeletePackage(int id)
        {
            var package = _context.PackageVersions.SingleOrDefault(p => p.Id == id);
            _context.PackageVersions.Remove(package);
        }

        public IEnumerable<PackageVersion> GetAllPackages()
        {
            return _context.PackageVersions.OrderBy(p => p.PackageName).ToList();
        }

        public object GetPackageById(int id)
        {
            return _context.PackageVersions.SingleOrDefault(p => p.Id == id);
        }

        public bool SaveAll()
        {
            return _context.SaveChanges() > 0;
        }

        public void UpdatePackage(PackageVersion updatePackage)
        {
            _context.Update(updatePackage);
        }

person Ray    schedule 06.02.2016    source источник
comment
Почему бы не использовать ограниченный контекст вместо использования нескольких?   -  person CodeNotFound    schedule 06.02.2016
comment
ты имеешь в виду _context.TableName?   -  person Ray    schedule 06.02.2016
comment
Может быть. Покажите нам реализацию репозитория.   -  person CodeNotFound    schedule 06.02.2016
comment
Добавлено обновление 1 в мой исходный пост.   -  person Ray    schedule 06.02.2016
comment
покажите нам, что находится в методе GetPackageById()   -  person Mir Gulam Sarwar    schedule 07.02.2016
comment
@janina, это обновление 1 в моем исходном посте с именем класса AutomationRepository.   -  person Ray    schedule 07.02.2016


Ответы (1)


Измените метод репозитория, как показано ниже. Это может помочь. Дайте нам знать, что происходит

public object GetPackageById(int id)
{ 
 return _context.PackageVersions.AsNoTracking().SingleOrDefault(p => p.Id ==id);
}
person Mir Gulam Sarwar    schedule 07.02.2016
comment
Рад, что это помогло. Но вам может понадобиться реорганизовать ваш репозиторий, чтобы избежать такой ситуации. - person Mir Gulam Sarwar; 08.02.2016