Ecco un modo funzionante - non l'unico, ma il più generalizzabile che ho trovato - per poter aggiornare attraverso un nuovo DataContext una entità precedentemente recuperata da un altro DataContext e poi utilizzata in libertà su è giù per i layer della nostra applicazione, in modalità connessa o disconnessa.
-
dal property grid del designer visual studio, mettete a Never la proprietà Update Check di tutte le colonne della entità
-
utilizzate nel seguente modo il metodo Attach del nuovo DataContext:
-
Passate un clone della entità da aggiornare invece che l'entità stessa, ottenuto con la funzione generica che vi indico sotto denominata CloneTableItem, che rimuove di fatto i riferimenti deferred a tutte le entità relazionate - che sono la causa di tutti i problemi del metodo Attach()
-
Utilizzate l'overload che prevede il secondo parametro bool asModified impostandolo su True
-
lanciate SubmitChanges()
In pratica il codice di aggiornamento rimane semplicissimo, come in questo esempio:
private static void UpdateCustomer(Customer c)
{
CompaniesDataContext dc = new CompaniesDataContext();
dc.Customers.Attach(CloneTableItem<Customer>(c), true);
dc.SubmitChanges();
}
dove CloneTableItem è una routine generica che potete riutilizzare per tutte le entità, siffatta:
using System.ComponentModel;
using System.Data.Linq.Mapping;
static public T CloneTableItem<T>(T src) where T : class, new()
{
T newInstance = new T();
PropertyDescriptorCollection srcProps = TypeDescriptor.GetProperties(src);
foreach (PropertyDescriptor prop in srcProps)
{
if (prop.Attributes[typeof(ColumnAttribute)] == null)
{
continue;
}
object val = prop.GetValue(src);
prop.SetValue(newInstance, val);
}
return newInstance;
}