En essayant d'établir une relation plusieurs à plusieurs dans mon contexte de base de données, j'ai obtenu l'erreur suivante lors de l'amorçage des données :

L'instance du type d'entité « Dossier » ne peut pas être suivie, car une autre instance avec la valeur de clé « {Id : dossier001 } » est déjà suivie. Lorsque vous attachez des entités existantes, assurez-vous qu'une seule instance d'entité avec une valeur de clé donnée est attachée.

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

}

La recherche de cette erreur aboutit principalement à des réponses parlant de la nécessité d'utiliser Scoped au lieu de Singleton pour enregistrer le service, mais ici, je configure mon service de cette façon : services.AddDbContext<DataContext>, certaines réponses indiquent également qu'il est nécessaire d'ajouter .AsNoTracking().

Alors comment puis-je me débarrasser de cette erreur ?

0
Sami-L 30 janv. 2020 à 00:45

1 réponse

Meilleure réponse

Vous n'avez pas réellement publié le code correspondant à l'erreur, mais je peux expliquer la cause de l'erreur.

Entity Framework a un changetracker, ce qui signifie qu'un contexte de base de données a une sorte de "dictionnaire secret" d'entités qu'il connaît, qu'il utilise comme un cache pour réduire les appels de base de données et garder une trace de ce que vous faites et ne changez pas sur ces entités. Ces entités sont stockées et référencées dans le suivi des modifications à l'aide de leur clé primaire.

Entity Framework ne peut stocker que un objet d'un type donné et d'une valeur PK donnée. Il ne peut pas suivre deux objets distincts qui ont la même valeur.

Pensez-y comme s'il s'agissait d'un dictionnaire, qui ne peut stocker qu'une seule valeur pour une valeur de clé donnée. Un dictionnaire écrase volontiers une valeur par une autre, mais EF refuse de le faire car cela est très susceptible de conduire à un comportement inattendu et à des bogues difficiles à résoudre.

Le code suivant générera la même erreur que celle que vous rencontrez :

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

Je ne peux pas vous dire où dans votre code cette erreur est causée car vous n'avez pas posté le code dans lequel cela peut se produire.

1
Flater 29 janv. 2020 à 23:31