如果我有LINQ对象:
public class SampleDataContext : DataContext { public TableCustomers { get { return this.GetTable (); } } public SampleDataContext( string connectionString ) : base( connectionString ) { } } [Table( Name="dbo.tblCustomers" )] public class Customer { private Guid? customerID; [Column( Storage="customerID", DbType="uniqueidentifier NOT NULL", IsPrimaryKey=true )] public Guid? CustomerID { get { return this.customerID; } set { this.customerID = value; } } private string customerName; [Column( Storage = "customerName", DbType = "nvarchar(255) NOT NULL" )] public string CustomerName { get { return this.customerName; } set { this.customerName = value; } } }
以及申请中的其他地方:
public static void DoSomethingWithCustomer( Customer customer ) { // some operations // now, I want save changes to the database }
如何获取追踪"客户"对象变化的DataContext实例?
编辑:为什么我不想将DataContext传递给方法.
1)总是传递2个对象而不是1个是整个应用程序的"丑陋"模式.
方法将需要每个业务对象的下一个参数.
收集将需要从"列表"更改为"列表>".
这两点都难以维护 - 开发人员必须每次都设置正确的DataContext实例(易于创建错误),尽管DataContext知道具体对象是否(或没有)附加到另一个DataContext.
2)我想(当前版本的应用程序使用它)处理来自不同"地方"的对象集合的"任何"业务逻辑(例如通过拖放浮动窗口).
Currentyl我们使用自定义类型的DataSet,因此有关更改的信息在数据行(DataRow =业务对象)中,并且获取它没有问题,或者创建克隆然后将其保存到数据库中.
凯文-我觉得你的痛苦......当你都在围绕你的业务对象的业务逻辑,有些时候你只是必须能够访问到DataContext到一个对象所属的,因为不知道不必把你的代码在DataContext menas在减少代码可维护性的地方.
我写了下面的代码(VB,我很害怕),它提供了一个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
这是一个C#版本:
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已订阅对象的OnPropertyChanging事件以监视对象生命周期内的更改这一事实.
如果这有用,请向上投票.
有关使用反射查找事件处理程序的更多信息,请 访问:http: //weblogs.asp.net/avnerk/archive/2007/03/29/reflecting-over-an-event.aspx http://www.bobpowell.net/ eventsubscribers.htm