Reputation:
Using EF6.1, I'm working with a table with a composite key as below:
How can I run an upsert method using Entity Framework?
I've written the following method but I've read that it should not be used for upserts, only migrations (please disregard the design pattern for now):
public void UpsertNumberOfMarkets(List<Entities.NumberOfMarkets> marketsList)
{
using (MyDbContext db = new MyDbContext())
{
foreach (var market in marketsList)
{
db.NumberOfMarkets.AddOrUpdate(market);
}
}
}
I'm also not certain that it works correctly. Any thoughts? I'd like to avoid deleting and inserting as we have an audit logging table for updates.
EDIT: I've written the following method which may handle this - is this the preferred approach?
public void UpsertNumberOfMarkets(List<Entities.NumberOfMarkets> marketsList)
{
using (MyDbContext db = new MyDbContext())
{
foreach (var market in marketsList)
{
var predicate = PredicateBuilder.True<Entities.NumberOfMarkets>();
predicate = predicate.And(n => n.ProjectId == market.ProjectId);
predicate = predicate.And(n => n.Year == market.Year);
var existingMarketEntry = db.NumberOfMarkets.AsExpandable().Where(predicate).FirstOrDefault();
if (existingMarketEntry != null)
existingMarketEntry.Markets = market.Markets;
else
{
db.NumberOfMarkets.Add(market);
}
}
db.SaveChanges();
}
}
Upvotes: 0
Views: 657
Reputation: 782
Yes.AddOrUpdate should only be used for migrations for below reason
It Updates all the values which are provided but mark all other values as NULL (which are not provided) which may not be the behaviour we want in real world application.
In your case you can follow below steps
using (MyDbContext db = new MyDbContext())
{
foreach (var market in marketsList)
{
var existingMarket =
db.Markets.FirstOrDefault(x => x.ProjectID == market.ProjectID && x.Year == market.Year);
if (existingMarket != null)
{
//Set properties for existing market
existingMarket.Year == market.Year
//etc
}
else
{
db.Markets.Add(market);
}
db.SaveChanges();
}
}
Upvotes: 1