Determinar a origem DataContext para um Linq para consulta SQL
-
11-07-2019 - |
Pergunta
Na minha aplicação tenho vários DataContexts que se conecta a diferentes bases de dados com esquemas diferentes. Em um controle de usuário personalizada I exibir os resultados da consulta e permitir que o usuário editar eles, e quando o usuário edita os dados Quero persistem as alterações para o banco de dados. Para fazer isso eu preciso de uma referência à fonte DataContext (ou pelo menos o tipo de fonte datacontext) para que eu possa fazer um DataContext.SubmitChanges();
Existe alguma maneira de determinar qual DataContext uma consulta vem? A classe DataQuery si é marcado como interno, então eu não posso acessar a sua propriedade de contexto, sem recorrer a hacks reflexão feias, por isso estou procurando uma abordagem mais limpo.
Existem (vários) maneiras de contornar este problema, passando ao longo de uma referência ao DataContext fonte, por exemplo, mas eu imagino que deve haver uma maneira mais simples de fazer isso.
Edit: O seguinte código funciona, mas é feio:
FieldInfo contextField = query.GetType().GetField("context", BindingFlags.Instance | BindingFlags.NonPublic);
if (query != null)
{
queryContext = contextField.GetValue(value) as DataContext;
}
Solução
Eu acho que você vai ter que simplesmente passar o DataContext ao código (manualmente). Desculpe.
Outras dicas
Sim - usando a reflexão é sobre a única maneira de determinar o DataContext ao qual a consulta pertence. É o mesmo com os objetos de dados que são criados quando a consulta é acionado.
O que se segue não responde estritamente questão de Rune, mas pode ser útil se você quiser usar o reflexo para determinar se um objecto de dados como anexado ao e monitorado por um contexto de dados:
O seguinte código define uma propriedade Contexto que pode ser colocado sobre um objecto de dados, e, em seguida, utilizada para retornar o DataContext (se alguma) que o objecto está associado.
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
Tome o cuidado de observar que o objeto só pode localizá-lo de DataContext se ele estiver ligado ao contexto com ChangeTracking ligado. Esta propriedade se baseia no fato de que o DataContext subscreveu evento OnPropertyChanging do objeto para a monitorizar as alterações ao longo do tempo de vida do objeto.
Se isso foi útil, por favor, up-voto este post.
Para obter mais informações sobre como usar a reflexão para encontrar manipuladores de eventos: http: //weblogs.asp. net / avnerk / Arquivo / 2007/03/29 / refletindo-over-an-event.aspx http://www.bobpowell.net/eventsubscribers.htm