У меня есть две таблицы.Пользовательская таблица имеет две ссылки на другую (идентичную) сущность, т.е. языки:
public class User
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public Language OrigLanguage { get; set; }
public Language Language { get; set; }
}
public class Language
{
public int Id { get; set; }
public string Name { get; set; }
}
EF создает таблицы правильно:
Таблица «Пользователи»: Id, FirstName, LastName, LanguageId, OrigLanguageId
Я могу добавлять пользователей с одинаковыми значениями для OrigLanguage и Language без каких-либо проблем.Как только я пытаюсь обновить существующего пользователя с теми же значениями, я получаю следующее сообщение об ошибке:
InvalidOperationException: экземпляр типа сущности 'Language' не может быть отслежен, поскольку другой экземпляр со значением ключа '{Id: 1} 'уже отслеживается.При подключении существующих объектов убедитесь, что подключен только один экземпляр объекта с данным значением ключа.
со следующим стеком:
Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap.ThrowIdentityConflict (запись InternalEntityEntry) Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap.Add (ключ TKey, запись InternalEntityEntry, bool updateDuplicate).InternalEntityEntry.SetEntityState (entityState oldState, entityState NewState, BOOL AcceptChanges) Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState (entityState entityState, BOOL AcceptChanges, Nullable forceStateWhenUnknownKey) Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.PaintAction (EntityEntryGraphNode узел,bool force) Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph (узел EntityEntryGraphNode, состояние TState, дескриптор функции).InternalEntityEntry rootEntry, EntityState entityState, bool forceStateWhenUnknownKey) Microsoft.EntityFrameworkCore.DbContext.SetEntityState (InternalEntityEntry запись, EntityState Entity).Data.Repository.UpdateAsync (T entity) в Repository.cs
В моем файле Startup.cs у меня есть следующие настройки для предотвращения отслеживания:
services.AddDbContext<DocLogDBContext>(
options => options.UseSqlServer(...)
.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)
В моем хранилище естьследующий код для обновления:
public override async Task<User> UpdateAsync(User entity)
{
// below two detachments have no effect
_context.Attach(entity.OrigLanguage).State = EntityState.Detached;
_context.Attach(entity.Language).State = EntityState.Detached;
_context.Attach(entity).State = EntityState.Modified;
await _context.SaveChangesAsync();
return entity;
}
Мой контроллер API выглядит следующим образом:
[HttpPost]
public virtual async Task<IActionResult> Edit(T model)
{
await _repository.UpdateAsync(model);
return Ok(model);
}
А это запрос от клиента:
Request URL: https://localhost:44344/api/User/Edit
Request Payload:
{
Id: 3
, FirstName: "Joe"
, LastName: "Frazer"
, Language: { Name: "english", ShortName: "en", Id: 1 }
, OrigLanguage: { Name: "english", ShortName: "en", Id: 1 }
}
Что мне здесь не хватает?