Determine el DataContext de origen para una consulta de Linq a Sql
-
11-07-2019 - |
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;
}
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