2010-08-18 11 views
11

Tengo este servicio que es singleton y single threaded y atiende a un montón de clientes de bajo volumen. Utiliza Entity Framework y Data en SQL Server.Entity Framework (3.5) - Rechazar cambios

Si cualquiera de las solicitudes del cliente para Guardar Datos falla, todas las solicitudes subsiguientes se están fallando ya que cada vez que se intenta guardar el objeto de datos original fallido.

¿Hay alguna manera de deshacer cambios en los datos EF cuando falla la operación de guardar?

Gracias de antemano

Respuesta

4

La respuesta a la pregunta es "No se pueden descartar los cambios en el contexto", en su lugar se debe descartar ObjectContext como explicó Marc.

11

entidad de modelos/ficha contextos/etc son mejor manejan como unidades de trabajo. Si necesita cancelarlo, simplemente descarte el contexto y comience con uno nuevo. ¡Y si tienes éxito, descartarlo de todos modos! Cada solicitud debe ser realmente utilizando datos en contextos distintos, de lo contrario se puede obtener una serie de problemas:

  • roscado (aunque suene has evitado esto por lo que es un único subproceso)
  • crecimiento de los datos (hay es un gestor de identidad; cada fila se toca se mantiene alrededor, varias veces, de hecho)
  • general de aislamiento etc
  • gestión de la conexión de por vida (acaparando una conexión abierta)
  • etc
+0

Sí, me di cuenta demasiado tarde ... pero el problema es que si eliminas el contexto del objeto e intentas conectar la base de datos, el rendimiento es demasiado malo. Así que decidimos mantener vivo el contexto Object. Intentando encontrar una manera de revertir los cambios en caso de falla. – Bhuvan

+0

@Bhuvan: esa afirmación de que "el rendimiento es malo" generalmente significa que está solicitando demasiados datos. He hecho ** montones ** de trabajo donde el contexto de datos tiene un alcance muy estrecho y está perfectamente desarrollado. –

3

se puede refrescar la entidad llamando

context.Refresh(RefreshMode.StoreWins, entity) 

así que no veo necesidad de RejectChanges.

+0

Gracias Sven .. Pero el problema con esto es que uno tiene que hacer un seguimiento de las entidades que se cambian. Tengo una cadena de entidades que deben ser comprometidas o rechazadas si falla el guardado. Creo que MS tiene que proporcionar una mejor manera de manejar esto. – Bhuvan

8

Nota: puede actualizar a EF 4.1 o 4.2 que hace que este trabajo fácil como un amuleto:

context.Entry(myEntity).State = EntityState.Unchanged; 

Por favor refiérase a this para el detalle.

Crear una clase parcial a su ObjectContext clase generada, e incluyen los métodos siguientes en el mismo (VB, lo siento - se debe transcribirse fácilmente a C#):

Public ReadOnly Property DirtyObjects() As IEnumerable(Of ObjectStateEntry) 
    Get 
    Return ObjectStateManager.GetObjectStateEntries(
     EntityState.Added Or 
     EntityState.Deleted Or 
     EntityState.Modified) 
    End Get 
End Property 


Public Overloads Sub Refresh() 
    For Each entry In DirtyObjects 
    Select Case entry.State 

     Case EntityState.Modified 
     Dim original = entry.OriginalValues 
     For Each prop In entry.GetModifiedProperties() 
      Dim ordinal = original.GetOrdinal(prop) 
      entry.CurrentValues.SetValue(ordinal, original(ordinal)) 
      RaisePropertyChanged(entry.Entity, prop) 
     Next 
     entry.AcceptChanges() 
     Case EntityState.Deleted 
     'I think I would need to call the above again, cuz it might be 
     'changed values on a Deleted-state entry too. 
     entry.ChangeState(EntityState.Unchanged) 
     Case EntityState.Added 
     entry.ChangeState(EntityState.Detached) 
     Case Else 
     'do nothing 
     Debug.Fail("It's not supposed to stop here.") 
    End Select 
    Next 
End Sub 

Heads up! En la nueva versión venidera, esta característica se ha vuelto muchísimo más fácil.

+1

. Gracias ... Gran solución ... – Bhuvan