Entity framework e Entity Copy

in C#, Informatica

Entity framework e Entity Copy

Recentemente ho dovuto modificare la logica di un’applicazione che gestiva i dati memorizzati all’interno di un db, tramite Entity Framework. In particolare l’esigenza è stata quella di filtrare una serie di record (in base a particolari condizioni), modificarne alcuni dati e copiarli (ricreandoli) all’interno del database.

Una soluzione possibile potrebbe essere quella di fare ereditare IClonable alle classi del model, utilizzando quindi il metodo Clone. Questo tipo di approccio, molto rapido per la gestione di classi, non è utilizzabile per la clonazione delle classi utilizzate come model perchè non ne consente di copiare gli attributi (es. le data annotation).

Un’altra soluzione potrebbe essere quella di utilizzare il mapping verso una nuova lista di oggetti, mappando manualmente le proprietà una ad una. Ovviamente se si procede per questa strada si potrebbe utilizzare librerie e tool dedicati, come automapper.

Ma esiste una soluzione più semplice.

Utilizzando le funzioni di filtro, come ad esempio Where  o FirstOrDefault è possibile estrarre i dati, memorizzarli all’interno di una lista (con il metodo .ToList() ), modificarne le proprietà e memorizzarli nel modo tradizionale. Ad esempio, nel seguente modo:

var dataList = _db.Table.Where(a=>a.id==1).ToList();
foreach(var element in dataList)
{
   element.EditUtcDatetime = DateTime.UtcNow; 
   id = 100;
}
_db.Table.Add(dataList);
_db.SaveChanges();

Il codice precedente funziona correttamente, ma ha un problema: se si prova ad aggiornare il valore di una proprietà chiave quest’ultima non viene aggiornata. Questo perchè, di default, Entity Framework tiene traccia del tracking delle proprietà che vengono elaborate. E’ possibile cambiare questo comportamento utilizzando .AsNoTracking:

var dataList = _db.Table.AsNoTracking.Where(a=>a.id==1).ToList();
foreach(var element in dataList)
{
   element.EditUtcDatetime = DateTime.UtcNow;
   id= 100;
}
_db.Table.Add(dataList);
_db.SaveChanges();

A questo è possibile copiare e modificare tutto il contenuto dei record, anche le chiavi.