'EF Core update an existing entity
I'm using EF Core and .NET 6 and I would like to essentially upsert an entity to a table - a fairly simple ask.
I have the following code:
var countries = GetCountries();
using (var scope = scopeFactory.CreateScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
foreach (var c in countries)
{
// check if the country already exists.
var exists = dbContext.Countries.Where(d => d.Id == c.Id).FirstOrDefault();
// if already exists - update (rather than add).
if (exists != null)
{
exists.Name = c.Name;
exists.DisplayName = c.DisplayName;
... // omitted other prop updates.
dbContext.Countries.Update(exists);
}
else
{
dbContext.Countries.Add(c);
}
}
await dbContext.SaveChangesAsync();
}
I was wondering - is there was a more efficient way to update without manually looking up then updating (it's not very performant).
Preferably, I was hoping there was a Merge method in EF Core but can't find anything useful (that's free...). Rather than doing the manual lookup and update in this way.
I'm probably missing something very obvious here - thanks for any pointers in advance!
Solution 1:[1]
EF Core do not have Merge, or similar for Upsert.
You can improve performance of your query by selecting existng items in one batch. Also you do not need to call Update, just change properties.
var countries = GetCountries();
using (var scope = scopeFactory.CreateScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
var countyIds = countries.Select(c => c.Id);
var existing = (await dbContext.Countries.Where(d => countyIds.Contains(d.Id))
.ToListAsync())
.ToDictionary(c => c.Id);
foreach (var c in countries)
{
// check if the country already exists.
if (existing.TryGetValue(c.Id, out var toUpdate))
{
// if already exists - update (rather than add).
toUpdate.Name = c.Name;
toUpdate.DisplayName = c.DisplayName;
... // omitted other prop updates.
}
else
{
dbContext.Countries.Add(c);
}
}
await dbContext.SaveChangesAsync();
}
Solution 2:[2]
public void InsertOrUpdate(Entity entity)
{
using (var context = new dbContext.Countries())
{
context.Entry(entity).State = entity.Id == 0 ?
EntityState.Added :
EntityState.Modified;
context.SaveChanges();
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | user19087368 |
