Frage

Wenn ich die LINQ-Objekte:

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; }
    }
}

und irgendwo anders in der Anwendung:

public static void DoSomethingWithCustomer( Customer customer ) {
    // some operations
    // now, I want save changes to the database
}

wie bekomme ich die Instanz von DataContext, welche Spuren, die Veränderungen der "customer" - Objekt?

Edit:Warum ich nicht wollen, übergeben Sie den DataContext in die Methode.

1) Verläuft immer 2 Objekte anstelle von " 1 "ugly" - Muster für die gesamte Bewerbung.

  • Methoden müssen folgenden parameter für jedes business-Objekt.
  • Die Sammlung wird geändert von "Liste" auf "Liste">".

Beide Punkte werden mehr schwer zu pflegen - Entwickler muss jeder-Zeit legt die korrekte Instanz von DataContext (einfach zu erstellen, ein Fehler), trotz der DataContext wissen, dass der Beton Objekt ist(oder nicht), die an einem anderen DataContext.

2) ich will (der aktuellen version der Anwendung verwenden), Prozess - "alle" business-Logik auf die Sammlung von Objekten, die kamen aus verschiedenen "Orten" ( floating windows durch drag & drop zum Beispiel ).

Currentyl verwenden wir custom typisierte DataSets, damit Informationen über änderungen in der data-Zeilen (DataRow = business-Objekt), und war kein problem zu erhalten, oder erstellen Sie einen Klon und dann speichern Sie es in die Datenbank.

War es hilfreich?

Lösung

Kevin - ich fühle deinen Schmerz ..., wenn Sie Business-Logik um Ihre Business-Objekte bauen, es gibt Zeiten, wenn Sie einfach wird Zugriff auf die Datacontext zu haben, zu dem ein Objekt gehört, seit nicht die Datacontext menas zu wissen, Ihren Code in Stellen zu setzen hat, die die Wartbarkeit des Codes zu reduzieren.

Ich schrieb den folgenden Code (VB, fürchte ich), die eine Context-Eigenschaft zeigt, die auf ein Datenobjekt platziert werden können, und dann verwendet, um die Datacontext zurück (falls vorhanden), dass das Objekt angebracht ist.

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

Hier ist eine C # Version:

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);
}

Achten Sie darauf, zu beachten, dass das Objekt nur es ist Datacontext orten kann, wenn sie gerade mit dem Kontext verbunden ist mit ChangeTracking eingeschaltet. Diese Eigenschaft beruht auf der Tatsache, dass die Datacontext an die OnPropertyChanging Veranstaltung Objekt abonniert hat, verändert sich über die Lebensdauer des Objekts zu überwachen.

Wenn das ist hilfreich, bitte up-Abstimmung dieses Beitrag.

Für weitere Informationen über Reflexion mit Event-Handler zu finden: http: //weblogs.asp. net / avnerk / Archiv / 2007/03/29 / reflektierende-over-an-event.aspx http://www.bobpowell.net/eventsubscribers.htm

Andere Tipps

Ein Teil des Spaßes von POCO ist, dass man nicht sicher sein kann, dass das Objekt weiß , die ihn verfolgt. Wenn das Objekt Data-Aware / lazy-Laden Eigenschaften hat, dann sind Sie könnte der Lage sein, den Kontext über Reflexion zu verfolgen, aber in Wirklichkeit wäre dies ein Chaos sein. Es wäre viel sauberer zu sein, einfach die Daten-Kontext, um den Code übergeben, die es braucht.

Die einfachste Sache zu tun ist, an den DataContext in Ihrer Methode.

Sie können jedoch auch in Erwägung ziehen, Ihre design, so dass Sie Folgen der Regel, dass "eine einzelne Methode sollte nur eine Aufgabe", in dem Fall, dass Sie würde nicht wollen, zu "Speichern" in der gleichen Methode, die Sie "Ändern".

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top