Определить исходный DataContext для запроса Linq to Sql - PullRequest
4 голосов
/ 25 ноября 2008

В моем приложении у меня есть несколько DataContexts, которые подключаются к разным базам данных с разными схемами. В пользовательском элементе управления я отображаю результаты запроса и позволяю пользователю редактировать их, а когда пользователь редактирует данные, я хочу сохранить изменения в базе данных. Для этого мне нужна ссылка на исходный DataContext (или, по крайней мере, на исходный тип datacontext), чтобы я мог сделать DataContext.SubmitChanges();

Есть ли способ определить, из какого DataContext поступает запрос? Сам класс DataQuery помечен как внутренний, поэтому я не могу получить доступ к его свойству context, не прибегая к уродливым способам отражения, поэтому я ищу более чистый подход.

Есть (несколько) способов обойти эту проблему, например, передать ссылку на исходный DataContext, но я предполагаю, что должен быть более простой способ сделать это.

Edit: Следующий код работает, но он уродлив:

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

Ответы [ 2 ]

2 голосов
/ 12 июня 2009

Да - использование отражения - это единственный способ определить DataContext, к которому относится запрос. То же самое относится и к объектам данных, которые создаются при запуске запроса.

Последующее не дает точного ответа на вопрос Руны, но может быть полезно, если вы хотите использовать отражение, чтобы определить, является ли объект данных присоединенным и отслеживаемым контекстом данных:

Следующий код определяет свойство Context, которое может быть помещено в объект данных, а затем использовано для возврата DataContext (если есть), к которому прикреплен объект.

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

Обратите внимание, что объект может найти свой DataContext, только если он в данный момент присоединен к контексту с включенным ChangeTracking. Это свойство основывается на том факте, что DataContext подписался на событие OnPropertyChanging объекта, чтобы отслеживать изменения в течение срока службы объекта.

Если это было полезно, пожалуйста, проголосуйте за этот пост.

Для получения дополнительной информации об использовании отражения для поиска обработчиков событий: http://weblogs.asp.net/avnerk/archive/2007/03/29/reflecting-over-an-event.aspx http://www.bobpowell.net/eventsubscribers.htm

0 голосов
/ 25 ноября 2008

Я думаю, вам нужно просто передать DataContext в код (вручную). К сожалению.

...