Определите исходный DataContext для запроса Linq to Sql.
-
11-07-2019 - |
Вопрос
В моем приложении есть несколько 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