2009-06-24 9 views
5

¿Es posible consultar el contexto, realizar un cambio en una entidad y luego volver a consultar el contexto y obtener un resultado devuelto que incluya la entidad modificada sin guardar cambios? ? (No quiero guardar cambios porque es posible que desee deshacer)Query Entity Framework incluidos los registros que no se han confirmado

Sé que puedo recuperar los cambios mediante el uso de GetObjectStateEntries, pero me interesa todo el conjunto de datos ... no solo las entidades modificadas.

Creo que la única forma de hacerlo es con cambios de guardado, pero ajuste un transactioncope alrededor de todo para poder hacer una reversión si mi condición no se cumple. ¿O me estoy perdiendo algo más fácil?

+0

¿Qué está tratando de lograr exactamente? ¿Por qué necesita acceder al nuevo conjunto antes de comprometerse? ¿Está tratando de hacer algún tipo de validación para evitar la duplicación o alguna otra cosa que requiera comparar las entidades insertadas/modificadas con todas las demás entidades en el conjunto? – Merritt

+0

Básicamente sí. No es tanto que quiera evitar una confirmación, sino que me gustaría actualizar otra entidad en función de la condición del estado actual de TODAS las entidades (cambio y sin cambios). Es una regla de negocios similar al flujo de trabajo. Lamentablemente, el estado puede cambiar en diferentes servicios que yo llamo (con un contexto en caché) que no lo hacen .savechanges(). Por lo tanto, el seguimiento de estos cambios es cada vez más difícil. – itchi

+0

Esto suena como una operación que podría ser realizada por otro servicio/aplicación (o en otro hilo al menos). ¿Podría crear un servicio de Windows (o un trabajo SQL) para manejar las actualizaciones? ¿Hay alguna razón por la que deba hacerse antes de guardar cambios()? – Merritt

Respuesta

3

¿Por qué no combinar el conjunto de entidades existentes con las que se agregarán? Probé esto y parece que trabajo- que no tiene en cuenta Elimina sin embargo, sino que debería ser capaz de obtener la idea:

// get the entities that have been inserted or modified 
var projects = myObjectContext.ObjectStateManager.GetObjectStateEntries(
    EntityState.Added | EntityState.Modified).Where(
      x => x.Entity is Project).Select(x=> (Project) x.Entity); 

// get existing entities, exclude those that are being modified 
var projects2 = myObjectContext.Projects.Where(
    BuildDoesntContainExpression<Project, int>(z => z.ProjectId, 
      projects.Select(x => x.ProjectId))); 

// Union the 2 sets 
var projects3 = projects.Union(projects2); 

BuildDoesntContainExpression: no se puede utilizar contiene, y por lo tanto no puede hacer lo contrario, con el EF por alguna razón, así que use este método:

private static Expression<Func<TElement, bool>> BuildDoesntContainExpression<TElement, TValue>( 
     Expression<Func<TElement, TValue>> valueSelector, IEnumerable<TValue> values) 
    {  
     if (null == valueSelector) 
     { 
      throw new ArgumentNullException("valueSelector"); 
     } 

     if (null == values) 
     { 
      throw new ArgumentNullException("values"); 
     }  

     ParameterExpression p = valueSelector.Parameters.Single();  

     // p => valueSelector(p) == values[0] || valueSelector(p) == ... 
     if (!values.Any())  
     {   
      return e => false;  
     }  

     var equals = values.Select(
      value => (Expression)Expression.NotEqual(valueSelector.Body, Expression.Constant(value, typeof(TValue))));  

     var body = equals.Aggregate<Expression>((accumulate, equal) => Expression.And(accumulate, equal));  

     return Expression.Lambda<Func<TElement, bool>>(body, p); 
    } 
+0

Sí, estaba considerando este tipo de enfoque también. ¿No debería haber una manera más fácil? Me sorprende que esta pregunta no sea más común. – itchi

+0

Te estoy dando la respuesta porque esto técnicamente funciona. Aunque, estoy seguro de que hay una manera más simple. Pero has pensado mucho en esto y mereces los puntos :) ¡Gracias! – itchi

Cuestiones relacionadas