Я отдаю себе отчет в том, что там несколько вопросов по этому поводу уже, но ни один из них на самом деле не решает мою проблему:Проверьте, если EF объект уже существует в текущем контексте
ПРИМЕНЕНИЕ ФОН
У меня есть веб-приложение, которое сначала использует код Entity Framework 6.1. Я использую шаблон репозитория в моем DAL, что означает, что у меня есть Repo, который запрашивает мой контекст и возвращает результаты в Services, который затем использует automapper для сопоставления моего объекта с моделью просмотра, а затем возвращает VM. Сервисы вызываются с помощью методов Web API.
Основываясь на вышеуказанной архитектуре, ясно, что я использую автономные объекты .
Проблема, с которой я сталкиваюсь, связана с обновлением существующих объектов (PUT). Поток выглядит следующим образом:
Угловая проблема HTTP PUT для метода WebAPI, передающего VM как параметр. Затем WebAPI вызывает метод Service, передавая параметр VM как параметр. Метод услуг преобразует виртуальную машину в объект EF с использованием automapper Затем метод службы вызывает соответствующий репозиторий, передавая в качестве параметра новый экземпляр отдельного объекта EF.
Пример метода обслуживания:
public async Task<List<DependantViewModel>> SaveDependants(int customerId, List<DependantViewModel> dependantViewModels)
{
var dependantEntities = Mapper.Map<List<DependantViewModel>, List<Dependant>>(dependantViewModels);
bool result = false;
foreach (var dependantEntity in dependantEntities)
{
result = await _dependantRepository.InsertOrUpdate(dependantEntity);
if (result != true)
{
// log errror
}
}
return Mapper.Map<List<Dependant>, List<DependantViewModel>>(dependantEntities);
}
BaseRepo:
public virtual async Task<bool> InsertOrUpdate(TE entity)
{
if (entity.Id == 0 || entity.Id == ModelState.New)
{
// insert new item
_context.Entry<TE>(entity).State = EntityState.Added;
}
else
{
// update existing item
_context.Entry<TE>(entity).State = EntityState.Modified;
_context.Entry<TE>(entity).Property(o => o.CreatedUserId).IsModified = false;
_context.Entry<TE>(entity).Property(o => o.CreatedDate).IsModified = false;
}
return await _context.SaveChangesAsync() > 0;
}
Исключение происходит при попытке установить:
_context.Entry (сущность) .State = EntityState.Modified;
Прикрепление объект типа «Business.Data.Entities.Customer.Dependant» не удалось, потому что другой сущность одного и того же типа уже есть один и тот же значение первичного ключа. Этот может произойти при использовании метода «Прикрепить» или установки состояния объекта в «Без изменений» или «Модифицировано», если любые объекты на графике имеют конфликтующие значения ключей. Это может быть связано с тем, что некоторые объекты являются новыми, а еще не получили значения ключей базы данных. В этом случае используйте метод «Добавить» или состояние «Добавлено» для отслеживания графика и , затем установите состояние не новых объектов в «Без изменений» или «Модифицировано», как .
Насколько я понимаю, это происходит из-за того, что отдельный объект должен быть прикреплен первым, прежде чем устанавливать состояние объекта. Проблема с этим заключается в том, что я не могу прикрепить объект, потому что он уже находится в контексте. Зависимость. По какой-то причине инфраструктура сущности уже отслеживает объект.
Есть ли способ, чтобы сначала проверить, существует ли сущность в контексте, а если нет, то присоедините, в противном случае, получить уже прикрепленный объект и примените изменения от измененного объекта к прикрепленному объекту, если это имеет смысл.
Цените любую обратную связь
ли вы использовать IoC контейнер? Если да, то какой Scope/Lifestyle вы используете для Context (реализация платформы Entity DbContext)? – Maris
Я использую IOC (autofac), и я использую InstancePerLifetimeScope – FaNIX
Вы должны использовать область '.InstancePerRequest()', потому что вы используете WebAPI. Это может быть причиной того, что вы получаете это исключение! – Maris