Sequence contains more than one element
This exception was caused when trying to use AddOrUpdate
with specifying identifier expression, like p => p.CategoryName
. There might be two Categories
that have the same name "Sport" or "Music".
This might also happen on Subcategories
and Services
, Subcategories
uses p => p.SubcategoryName
and Services
uses p => p.ServiceType
.
You need to clean the duplicate entry first on database. This is a must, since you want to use AddOrUpdate
, internally this code will use SingleOrDefault
and if there is found more than one match element, exception will be thrown.
Object reference not set to an instance of an object
This error is probably caused by this code.
Category = { CategoryName = "Sport" },
Subcategory = { SubcategoryName = "Football" }
Creating new Service
will have null Category
by default, you can't just directly set the CategoryName
.
The problem occurs with when I add new Services. I want to use the already added categories and subcategories.
The Categories
and Subcategories
should be stored on variables so it can be used by 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
}
);
But above code still has problem, if service is new entity, the existing sport category and the existing football subcategory will also be added. You can read this article for further explanation.
Solution
You need to also have foreign key values on Service
not only foreign key references to prevent adding existing category and existing subcategory.
[ForeignKey("Category")]
public int CategoryId { get; set; }
[ForeignKey("Subcategory")]
public int SubcategoryId { get; set; }
Then run the migration.
Add-Migration AddServiceFKValues
And assign temporary primary key manually and use it when defining service. This temporary primary keys are not needed when dealing with existing entities, but there might be another problem if there is more than one new category or subcategory. To prevent that, it's better to use temporary primary keys, after calling AddOrUpdate
, each entity primary keys will be updated if they are existing entities.
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
}
);
Then update the database.
Update-Database