Вопрос

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

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

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

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

FieldInfo contextField = query.GetType().GetField("context", BindingFlags.Instance | BindingFlags.NonPublic);
if (query != null)
{
  queryContext = contextField.GetValue(value) as DataContext;
}
Это было полезно?

Решение

Я думаю, вам придется просто передать DataContext в код (вручную).Извини.

Другие советы

Да. Использование отражения — это практически единственный способ определить 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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top