EF Core не может обновить сущность с двумя навигационными свойствами для одного и того же объекта (другой сущности) - PullRequest
0 голосов
/ 29 мая 2019

У меня есть две таблицы.Пользовательская таблица имеет две ссылки на другую (идентичную) сущность, т.е. языки:

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 }
}

Что мне здесь не хватает?

1 Ответ

1 голос
/ 29 мая 2019

Мы можем решить с помощью атрибута "[ForeignKey (" xxxxx ")]" в классе poco.Здесь я пытаюсь исправить код, как показано ниже:

   public class User
   {
       public int Id { get; set; }
       public string FirstName { get; set; }
       public string LastName { get; set; }
       [ForeignKey("OrigLanguage")]
       public int OrigLanguageId { get; set; }
       [ForeignKey("Language")]
       public int LanguageId { get; set; }

       public Language OrigLanguage { get; set; }
       public Language Language { get; set; }
   }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...