La sequenza contiene più di un errore di elemento nelle migrazioni EF CF.

Ho creato alcuni modelli, aggiunto la migrazione e poi fatto un’operazione di aggiornamento del database, anche se alla mia ultima operazione di database di aggiornamento ho ricevuto il messaggio di errore che diceva:

La sequenza contiene più di un elemento

Qui sotto puoi trovare la mia configurazione di migrazione:

context.Categories.AddOrUpdate(p => p.CategoryName, new Category { CategoryName = "Sport" }, new Category { CategoryName = "Music" } ); context.Subcategories.AddOrUpdate(p => p.SubcategoryName, new Subcategory { SubcategoryName = "Football" }, new Subcategory { SubcategoryName = "Basketball" }, new Subcategory { SubcategoryName = "Piano" }, new Subcategory { SubcategoryName = "Violin" } ); context.Services.AddOrUpdate(p => p.ServiceType, new Service { ServiceType = "Football player", Category = { CategoryName = "Sport" }, Subcategory = { SubcategoryName = "Football" } }, new Service { ServiceType = "Piano lessons", Category = { CategoryName = "Music" }, Subcategory = { SubcategoryName = "Piano" } } ); 

Il problema si verifica quando aggiungo nuovi servizi. Ho già categorie e sottocategorie, e se mi piace Category = new Category { CategoryName = "Music" } allora funziona ma ottengo due volte Music entry nel mio database (per questo esempio). Voglio utilizzare le categorie e le sottocategorie già aggiunte. Di seguito anche le definizioni dei miei modelli.

 public class Category { [Key] public int CategoryID { get; set; } public string CategoryName { get; set; } } // Subcategory is defined the same way... public class Service { public int ServiceID { get; set; } public string ServiceType { get; set; } public virtual Category Category { get; set; } public virtual Subcategory Subcategory { get; set; } } 

Qualche idea su come risolverlo?

La sequenza contiene più di un elemento

Questa eccezione è stata causata quando si tenta di utilizzare AddOrUpdate con l’espressione di identificatore specificata, come p => p.CategoryName . Potrebbero esserci due Categories che hanno lo stesso nome “Sport” o “Musica”.

Questo potrebbe accadere anche su Subcategories e Services , le Subcategories utilizzano p => p.SubcategoryName e Services utilizza p => p.ServiceType .

È necessario pulire la voce duplicata prima sul database. Questo è un must, dal momento che si desidera utilizzare AddOrUpdate , internamente questo codice utilizzerà SingleOrDefault e se viene trovato più di un elemento di corrispondenza, verrà generata un’eccezione.

Il riferimento non impostato su un’istanza di un object

Questo errore è probabilmente causato da questo codice.

 Category = { CategoryName = "Sport" }, Subcategory = { SubcategoryName = "Football" } 

La creazione di un nuovo Service avrà una Category null per impostazione predefinita, non è ansible impostare direttamente CategoryName .

Il problema si verifica quando aggiungo nuovi servizi. Voglio utilizzare le categorie e le sottocategorie già aggiunte.

Le Categories e le Subcategories devono essere archiviate su variabili in modo che possano essere utilizzate dal Service .

 var sportCategory = new Category { CategoryName = "Sport" }; var musicCategory = new Category { CategoryName = "Music" }; context.Categories.AddOrUpdate(p => p.CategoryName, sportCategory, musicCategory); var footballSub = new Subcategory { SubcategoryName = "Football" }; var basketballSub = new Subcategory { SubcategoryName = "Basketball" }; var pianoSub = new Subcategory { SubcategoryName = "Piano" }; var violinSub = new Subcategory { SubcategoryName = "Violin" }; context.Subcategories.AddOrUpdate(p => p.SubcategoryName, footbalSub, basketballSub , pianoSub, violinSub); context.Services.AddOrUpdate(p => p.ServiceType, new Service { ServiceType = "Football player", Category = sportCategory, Subcategory = footballSub }, new Service { ServiceType = "Piano lessons", Category = musicCategory, Subcategory = pianoSub } ); 

Ma il codice sopra riportato ha ancora problemi, se il servizio è una nuova quadro, verranno aggiunte anche la categoria sportiva esistente e la sottocategoria di calcio esistente. Puoi leggere questo articolo per ulteriori spiegazioni.

Soluzione

È necessario anche avere valori di chiave esterna in Service non solo riferimenti a chiave esterna per impedire l’aggiunta di categorie esistenti e sottocategorie esistenti.

 [ForeignKey("Category")] public int CategoryId { get; set; } [ForeignKey("Subcategory")] public int SubcategoryId { get; set; } 

Quindi eseguire la migrazione.

 Add-Migration AddServiceFKValues 

E assegnare manualmente la chiave primaria temporanea e usarla quando si definisce il servizio. Queste chiavi primarie temporanee non sono necessarie quando si tratta di quadro esistenti, ma potrebbe esserci un altro problema se esiste più di una nuova categoria o sottocategoria. Per evitare ciò, è meglio utilizzare le chiavi primarie temporanee, dopo aver chiamato AddOrUpdate , ogni chiave primaria dell’entity framework verrà aggiornata se sono entity framework esistenti.

 var sportCategory = new Category { CategoryID = 1000, CategoryName = "Sport" }; var musicCategory = new Category { CategoryID = 1001, CategoryName = "Music" }; context.Categories.AddOrUpdate(p => p.CategoryName, sportCategory, musicCategory); var footballSub = new Subcategory { SubcategoryID = 1000, SubcategoryName = "Football" }; var basketballSub = new Subcategory { SubcategoryID = 1001, SubcategoryName = "Basketball" }; var pianoSub = new Subcategory { SubcategoryID = 1002, SubcategoryName = "Piano" }; var violinSub = new Subcategory { SubcategoryID = 1003, SubcategoryName = "Violin" }; context.Subcategories.AddOrUpdate(p => p.SubcategoryName, footbalSub, basketballSub , pianoSub, violinSub); context.Services.AddOrUpdate(p => p.ServiceType, new Service { ServiceType = "Football player", CategoryID = sportCategory.CategoryID, SubcategoryID = footballSub.SubcategoryID }, new Service { ServiceType = "Piano lessons", CategoryID = musicCategory.CategoryID, SubcategoryID = pianoSub.SubcategoryID } ); 

Quindi aggiorna il database.

 Update-Database