.net - tutorial - linq vbnet
Determine la fuente DataContext para una consulta de Linq a SQL (2)
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 mantener los cambios en la base de datos. Para hacer eso necesito una referencia al DataContext de origen (o al menos el tipo de contexto de datos de origen) para poder hacer un DataContext.SubmitChanges();
¿Hay alguna manera 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) maneras de solucionar este problema, pasando por una referencia al DataContext de origen, por ejemplo, pero imagino que debe haber una manera más simple 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;
}
Creo que tendrás que pasar el DataContext al código (manualmente). Lo siento.
Sí, utilizar 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 usar la reflexión para determinar si un Objeto de Datos está adjuntado y monitoreado 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 usa para devolver el DataContext (si existe) al que está unido 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 localizar su DataContext si está actualmente conectado al contexto con ChangeTracking activado. Esta propiedad se basa en el hecho de que DataContext se ha suscrito al evento OnPropertyChanging del objeto para monitorear los cambios a lo largo de la vida del objeto.
Si esto fue útil, por favor vote esta publicación.
Para obtener más información sobre el uso de la reflexión para encontrar controladores de eventos: http://weblogs.asp.net/avnerk/archive/2007/03/29/reflecting-over-an-event.aspx http://www.bobpowell.net/ eventsubscribers.htm