In questa risposta SO su Entity Framework e MERGE, l'esempio su come codificarlo è questo:
public void SaveOrUpdate(MyEntity entity)
{
if (entity.Id == 0)
{
context.MyEntities.AddObject(entity);
}
else
{
context.MyEntities.Attach(entity);
context.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified);
}
}
Ciò presuppone che tu già sappia se l'entità che vuoi espandere esiste o no; in questo caso controlli entity.Id
. Ma cosa succede se non sai se l'oggetto esiste o no? Ad esempio, nel mio caso, sto importando record da un venditore nel mio database e un determinato record potrebbe o non essere già stato importato. Voglio aggiornare il record se esiste, altrimenti aggiungilo. Ma l'ID del venditore è già impostato in entrambi i casi.
Non riesco a vedere alcun modo per farlo a meno che non chieda semplicemente al database se il record esiste già, il che sconfigge l'intero scopo di MERGE.
Se si desidera un comando UPSERT del database atomico senza una stored procedure e non si è preoccupati del contesto che si sta aggiornando, è opportuno ricordare che è possibile anche racchiudere un'istruzione MERGE
incorporata in una chiamata ExecuteSqlCommand
:
public void SaveOrUpdate(MyEntity entity)
{
var sql = @"MERGE INTO MyEntity
USING
(
SELECT @id as Id
@myField AS MyField
) AS entity
ON MyEntity.Id = entity.Id
WHEN MATCHED THEN
UPDATE
SET Id = @id
MyField = @myField
WHEN NOT MATCHED THEN
INSERT (Id, MyField)
VALUES (@Id, @myField);"
object[] parameters = {
new SqlParameter("@id", entity.Id),
new SqlParameter("@myField", entity.myField)
};
context.Database.ExecuteSqlCommand(sql, parameters);
}
Questo non è bello perché funziona al di fuori dell'astrazione di EF sulle entità ma ti permetterà di sfruttare il comando MERGE
.
AddOrUpdate è una buona soluzione, tuttavia non è scalabile . È necessario un round-trip del database per verificare se l'entità esiste già e un round-trip per inserire o aggiornare l'entità. Quindi, se si salvano 1000 entità, verrà eseguito il 2000 round-trip del database.
Disclaimer : sono il proprietario del progetto Entity Framework Extensions
Questa libreria consente di eseguire un'operazione di unione all'interno di Entity Framework allo stesso tempo migliora notevolmente le prestazioni. Per salvare 1000 entità sarà richiesto solo 1 round-trip del database.
// Easy to use
context.BulkMerge(customers)
// Easy to customize
context.BulkMerge(customers, operation => {
operation.ColumnPrimaryKeyExpression =
customer => customer.Code;
});