凯文-我感觉到你的痛苦。。。当您围绕业务对象构建业务逻辑时,有时您只需
有
我编写了以下代码(恐怕是VB),它提供了一个可以放置在数据对象上的上下文属性,然后用于返回对象所附加的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
public DataContext GetMyDataContext()
{
// Find the StandardChangeTracker listening to property changes on this object.
// If no StandardChangeTracker is listening, then this object is probably not
// attached to a data context.
var eventField = this.GetType().GetField("PropertyChangingEvent", BindingFlags.NonPublic | BindingFlags.Instance);
var eventDelegate = eventField.GetValue(this) as Delegate;
if (eventDelegate == null)
return null;
eventDelegate = eventDelegate.GetInvocationList().FirstOrDefault(
del => del.Target.GetType().FullName == "System.Data.Linq.ChangeTracker+StandardChangeTracker");
if (eventDelegate == null)
return null;
// Dig through the objects to get the underlying DataContext.
// If the following fails, then there was most likely an internal change
// to the LINQ-to-SQL framework classes.
var targetField = eventDelegate.Target;
var servicesField = targetField.GetType().GetField("services", BindingFlags.NonPublic | BindingFlags.Instance);
var servicesObject = servicesField.GetValue(targetField);
var contextField = servicesObject.GetType().GetField("context", BindingFlags.NonPublic | BindingFlags.Instance);
return (DataContext)contextField.GetValue(servicesObject);
}
请注意,如果对象当前连接到打开了ChangeTracking的上下文,则该对象只能定位其DataContext。此属性依赖于DataContext已订阅对象的OnPropertyChange事件以监视对象生命周期内的更改这一事实。
如果这有帮助,请在这篇文章上投票。
有关使用反射查找事件处理程序的详细信息: