Базовая структура Entity - экземпляр типа объекта не может быть отслежен, потому что другой экземпляр со значением ключа уже отслеживается - PullRequest
0 голосов
/ 30 января 2020

Пытаясь установить sh отношение многие ко многим в моем контексте БД, при заполнении данных я получил следующую ошибку:

Экземпляр типа сущности 'Папка' не может быть отслежен, поскольку другой экземпляр со значением ключа '{Id: folder001}' уже отслеживается. При присоединении существующих объектов убедитесь, что подключен только один экземпляр объекта с данным значением ключа.

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);
    builder.Entity<UserFolder>(userFolder =>
    {
        userFolder.HasKey(ud => new { ud.UserId, ud.FolderId });

        userFolder.HasOne(uf => uf.Folder)
            .WithMany(f => f.Users)
            .HasForeignKey(uf => uf.FolderId)
            .IsRequired();

        userFolder.HasOne(uf => uf.User)
            .WithMany(f => f.Folders)
            .HasForeignKey(uf => uf.UserId)
            .IsRequired();
    });
}

_

public class Folder
{

    public string Id { get; set; }
    public string FolderName { get; set; }

    public virtual ICollection<UserFolder> Users { get; set; }
}

_

public class User
{

    public string Id { get; set; }
    public string UserName { get; set; }

    public virtual ICollection<UserFolder> Folders { get; set; }
}

_

public class UserFolder
{
    public string UserId { get; set; }
    public virtual User User { get; set; }

    public string FolderId { get; set; }
    public virtual Folder Folder { get; set; }

}

Поиск этой ошибки в основном приводит к ответам, говорящим о необходимости использовать Scoped вместо Singleton для регистрации службы, но здесь я настраиваю свою службу следующим образом: services.AddDbContext<DataContext>, также некоторые ответы скажем, что нужно добавить .AsNoTracking().

Так как мне избавиться от этой ошибки?

1 Ответ

1 голос
/ 30 января 2020

Вы на самом деле не опубликовали код, который имеет отношение к ошибке, но я могу объяснить причину ошибки.

В Entity Framework есть средство отслеживания изменений, что означает, что контекст БД имеет вид " секретный словарь "сущностей, о которых он знает, который он использует как кеш для сокращения вызовов базы данных и отслеживания того, что вы делаете, и не изменяет эти сущности. Эти сущности хранятся и на них ссылаются в трекере изменений с использованием их первичного ключа.

Entity Framework может хранить только один объект заданного типа и заданного значения PK. Он не может отслеживать два разных объекта, которые имеют одинаковое значение.

Думайте об этом, как будто это словарь, который может хранить только одно значение для данного значения ключа. Словарь успешно перезаписывает одно значение другим, но вместо этого EF отказывается это сделать, поскольку это очень вероятно приведет к непредвиденному поведению и затруднит устранение ошибок.

Следующий код выдаст ту же ошибку, что и вы ' Вы испытываете:

using(var db = new MyContext())
{
    Foo foo1 = new Foo() { Id = 123 };
    Foo foo2 = new Foo() { Id = 123 }; // different object in memory, same PK identifier

    db.Foos.Attach(foo1);
    db.Foos.Attach(foo2); // exception! 
}

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

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