Pregunta

En mi aplicación tengo varios DataContexts que se conectan a diferentes bases de datos con diferentes esquemas. En un control de usuario personalizado, muestro los resultados de la consulta y dejo que el usuario los edite, y cuando el usuario edita los datos, deseo que los cambios persistan en la base de datos. Para hacer eso, necesito una referencia al DataContext de origen (o al menos el tipo de datacontext de origen) para poder hacer un DataContext.SubmitChanges();

¿Hay alguna forma de determinar de qué DataContext proviene una consulta? La clase DataQuery está marcada como interna, por lo que no puedo acceder a su propiedad de contexto sin recurrir a hacks de reflexión feos, por lo que estoy buscando un enfoque más limpio.

Hay (varias) formas de solucionar este problema, pasando una referencia al DataContext de origen, por ejemplo, pero imagino que debe haber una forma más sencilla de hacerlo.

Editar: El siguiente código funciona, pero es feo:

FieldInfo contextField = query.GetType().GetField("context", BindingFlags.Instance | BindingFlags.NonPublic);
if (query != null)
{
  queryContext = contextField.GetValue(value) as DataContext;
}
¿Fue útil?

Solución

Creo que simplemente tendrá que pasar el DataContext al código (manualmente). Lo siento.

Otros consejos

Sí, el uso de la reflexión es la única forma de determinar el DataContext al que pertenece la consulta. Es lo mismo con los objetos de datos que se crean cuando se activa la consulta.

Lo que sigue no responde estrictamente a la pregunta de Rune, pero puede ser útil si desea utilizar la reflexión para determinar si un Objeto de datos está adjunto y supervisado por un Contexto de datos:

El siguiente código define una propiedad de contexto que se puede colocar en un objeto de datos y luego se utiliza para devolver el DataContext (si lo hay) al que está adjunto el objeto.

Private Const StandardChangeTrackerName As String = "System.Data.Linq.ChangeTracker+StandardChangeTracker"

Private _context As DataClasses1DataContext
Public Property Context() As DataClasses1DataContext
    Get
        Dim hasContext As Boolean = False
        Dim myType As Type = Me.GetType()
        Dim propertyChangingField As FieldInfo = myType.GetField("PropertyChangingEvent", BindingFlags.NonPublic Or BindingFlags.Instance)
        Dim propertyChangingDelegate As PropertyChangingEventHandler = propertyChangingField.GetValue(Me)
        Dim delegateType As Type = Nothing

        For Each thisDelegate In propertyChangingDelegate.GetInvocationList()
            delegateType = thisDelegate.Target.GetType()
            If delegateType.FullName.Equals(StandardChangeTrackerName) Then
                propertyChangingDelegate = thisDelegate
                hasContext = True
                Exit For
            End If
        Next

        If hasContext Then
            Dim targetField = propertyChangingDelegate.Target
            Dim servicesField As FieldInfo = targetField.GetType().GetField("services", BindingFlags.NonPublic Or BindingFlags.Instance)
            If servicesField IsNot Nothing Then

                Dim servicesObject = servicesField.GetValue(targetField)

                Dim contextField As FieldInfo = servicesObject.GetType.GetField("context", BindingFlags.NonPublic Or BindingFlags.Instance)

                _context = contextField.GetValue(servicesObject)

            End If
        End If

        Return _context
    End Get
    Set(ByVal value As DataClasses1DataContext)

        _context = value

    End Set

End Property

Tenga en cuenta que el objeto solo puede ubicar su DataContext si actualmente está adjunto al contexto con ChangeTracking activado. Esta propiedad se basa en el hecho de que DataContext se ha suscrito al evento OnPropertyChanging del objeto para supervisar los cambios durante la vida útil del objeto.

Si esto fue útil, vote por favor esta publicación.

Para obtener más información sobre el uso de la reflexión para buscar controladores de eventos: http: //weblogs.asp. net / avnerk / archive / 2007/03/29 / reflecting-over-an-event.aspx http://www.bobpowell.net/eventsubscribers.htm

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top