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;
}
Foi útil?

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top