Aquí hay un pequeño experimento que hice:Valores de datos de almacenamiento en caché de Linq: ¿problema importante de concurrencia?
MyClass obj = dataContext.GetTable<MyClass>().Where(x => x.ID = 1).Single();
Console.WriteLine(obj.MyProperty); // output = "initial"
Console.WriteLine("Waiting..."); // put a breakpoint after this line
obj = null;
obj = dataContext.GetTable<MyClass>().Where(x => x.ID = 1).Single(); // same as before, but reloaded
Console.WriteLine(obj.MyProperty); // output still = "initial"
obj.MyOtherProperty = "foo";
dataContext.SubmitChanges(); // throws concurrency exception
Cuando golpeo el punto de interrupción después de la línea 3, voy a una ventana de consulta SQL y cambiar manualmente el valor de "actualización". Entonces sigo corriendo. ¡Linq no recarga mi objeto, sino que reutiliza el que tenía previamente en la memoria! ¡Este es un gran problema para la concurrencia de datos!
¿Cómo se desactiva este caché oculto de objetos que obviamente Linq guarda en la memoria?
EDIT - En pocas palabras, es impensable que Microsoft haya podido dejar un abismo tan grande en el marco de Linq. El código anterior es una versión simplificada de lo que estoy haciendo en realidad, y puede haber pequeñas sutilezas que me he perdido. En resumen, apreciaría que hicieras tu propia experimentación para verificar que mis hallazgos anteriores sean correctos. Alternativamente, debe haber algún tipo de "interruptor secreto" que haga que Linq sea robusto frente a las actualizaciones de datos concurrentes. ¿Pero que?
+1 ¡Dios mío, realmente es un Gotcha! Tengo que agregar eso al C# Gotcha KB ... –
Peor aún, si sigues sus consejos allí y configura ObjectTrackingEnabled = false, solo puedes leer desde el DB; ¡no puedes hacer SubmitChanges! ¡Eso REALMENTE hace la vida difícil! –
Aquí hay un enlace al C# gotcha KB: http://stackoverflow.com/questions/241134/what-is-the-worst-c-net-gotcha –