如果我有皇宫的对象:

public class SampleDataContext : DataContext {
    public Table<Customer> Customers { get { return this.GetTable<Customer>(); } }
    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
}

我如何可以获得的实例的属性,它的轨道变化的"客户"的对象?

编辑:为什么我不想通过的属性进的方法。

1)通过总是2对象,而不是1是"丑陋的"模式对于整个应用程序。

  • 方法将需要下参数用于每个企业的对象。
  • 集会需要改变,从"名单",以"列表>".

这两点将更加难以维持开发必须在每一个时间设置正确的实例属性(容易地创建一个错误),尽管有的属性知道那个的具体目的是(或不是)附着于另一个属性.

2)我想(目前版本的应用程序的使用)过程中"任意"的商务逻辑上收集的对象来自不同的"地方"(浮windows通过拖拉为例)。

Currentyl我们使用的定义类型的数据集,因此有关信息的变化是在行数据(数据行=商务对象),并不是问题要得到它,或者创建一个克隆和然后把它保存入数据库。

有帮助吗?

解决方案

凯文-我感觉到你的痛苦...当你建筑的业务逻辑围绕你的业务对象,有的时候你只是 访问的属性,其对象属于,由于不知道的属性menas具有把你的代码,在地方,减少可维护性的代码。

我写下代码(VB,我很害怕),其中提供了背景下的财产可以被放置到一个对象的数据,然后用于返回的属性(如果有的话),目的是连接。

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交换。这个酒店依赖于一个事实,即属性已经订购的对象的OnPropertyChanging事件监测的变化超过使用寿命的物体。

如果这是有帮助的,请投票,这个员额。

更多信息的使用反映找到事件处理程序:http://weblogs.asp.net/avnerk/archive/2007/03/29/reflecting-over-an-event.aspx http://www.bobpowell.net/eventsubscribers.htm

其他提示

其中的乐趣的 POCO的 是,你不能确定对象 知道 是谁跟踪他。如果象有数据-知道/延迟装载性能,然后你 可能会 能够跟踪的背景下通过的反映,但在现实中,这将是一个烂摊子。这将是迄今为止清洁简单地通过数据方面的代码需要它。

最简单的事情就是通过所属性进入你的方法。

但是,你也可以考虑更改你的设计这样,你遵守规则,"一个方法应该只有一个目的",在这种情况下你不会想"保存"在相同的方法"修改".

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top