2009-06-15 16 views
1

Ich bin neu bei LINQToSQL. Gibt es eine Möglichkeit, die Methoden "InsertOnSubmit" oder "DeleteOnSubmit" der DataContext-Klasse für eine bestimmte Entität zu überschreiben?DataContext-Methoden in LINQToSQL überschreiben

Wie zum Beispiel habe ich eine Datenbanktabelle namens Kunden, die ein boolesches Feld "IsDeleted" hat, das gilt, wenn der Benutzer einen Kundendatensatz aus der Benutzeroberfläche löscht. Wenn ich das _myDataContext.Customers.DeleteOnSubmit (..) aufrufen werde, löscht es standardmäßig den Datensatz aus der Tabelle, den ich nicht möchte. Stattdessen möchte ich, dass es logisch gelöscht wird, indem Sie das Feld "IsDeleted" auf "True" setzen.

Eine Möglichkeit besteht darin, das Objekt abzurufen und die Update-Methode (statt Löschen) aufzurufen, nachdem der Eigenschaftswert festgelegt wurde. Das wird auch funktionieren, aber nur aus Neugier möchte ich wissen, ob die Standard-DataContext-Methoden (InsertOnSubmit, DeleteOnSubmit usw.) überschreibbar sind? Und wenn ja, wie?

Dank

+0

Ich werde wieder Ihren Kommentar aktualisieren helfen (hast du die bearbeiten, btw?) –

Antwort

0

Soweit ich weiß, kein sind sie nicht. Wenn du es nicht löschen willst ... rufe nicht delete auf! Doch einige andere Optionen:

  • könnten Sie das Löschen einer gespeicherten Prozedur zuordnen, die nur die Flagge auf der Datenbank setzt
  • Sie in der Lage sein kann SubmitChanges und Fix-Up-Änderungen (via GetChangetSet) außer Kraft zu setzen, bevor Rufen Sie base.SubmitChanges - aber ich bin zweifelhaft, ob dies eine gute Idee ist; Möglicherweise muss der Artikel zum Beispiel neu eingefügt werden.

Code:

partial class MyDataContext { 
    public override void SubmitChanges(ConflictMode failureMode) { 
     var delta = GetChangeSet(); 
     foreach(var record in delta.Deletes.OfType<Customer>()) { 
      Customers.InsertOnSubmit(record); 
      record.IsDeleted = true; 
     } 
     base.SubmitChanges(failureMode); 
    } 
} 

Natürlich, wenn es flexibler zu sein braucht man GetTable() (statt einer starren Customers Eigenschaft) verwenden möchten.


Aktualisierungen zu Ihrem Kommentar; Ich glaube ehrlich gesagt nicht, dass Sie es tun können an diesem Punkt; Das "10 Orte" -Ding ... IMO Sie sollten den Datenkontext hinter einer Repository-Schnittstelle sowieso verstecken, so dass alle 10 Orte eine Methode wie CreateUser aufrufen würden, die sich mit dem Datenkontext und der notwendigen Logik beschäftigt (vielleicht mit einem separate Business-Logik-Klasse, um einige der Regeln zu handhaben). Außerdem sollte die Eindeutigkeit normalerweise auf Datenbankebene behandelt werden (über eine Einschränkung), da Bedenken hinsichtlich der Nebenläufigkeit bestehen.

Aber das zu tun, was Sie wollen, bevor Sie versuchen, sie zu retten:

partial class MyDataContext { 
    public override void SubmitChanges(ConflictMode failureMode) { 
     var delta = GetChangeSet(); 
     foreach(var record in delta.Inserts.OfType<User>()) { 
      if(Users.Any(x=>x.Name == record.Name) {...throw an exception...} 
     } 
     base.SubmitChanges(failureMode); 
    } 
} 
+0

Okay, hier ist der eigentliche Anwendungsfall . Bitte lassen Sie mich wissen, wie dies am besten erreicht werden kann. Ich habe einen Tabellennamen Benutzer und ich möchte sicherstellen, dass der Benutzername Benutzer versucht, Hinzufügen ist nicht bereits vorhanden. Ich kann sehr einfach eine Abfrage ausführen, um dies vor dem Aufruf von _DataContext.Users.InsertOnSubmit (objUser) zu überprüfen, aber was ist, wenn diese Operation von 10 Stellen in meiner Anwendung ausgeführt wird? Ich muss diesen Check an allen 10 Orten hinzufügen.Wenn ich stattdessen die InsertOnSubmit-Methode für DataContext.Users überschreibe und diese Überprüfung vor dem Aufruf von base.InsertOnSubmit vorstelle, muss ich es nur an 1 Stelle tun. –

+0

Es muss irgendwie so sein. Dies ist ein sehr häufiges Szenario. –

+0

Ich glaube, das ist, was ich vermisst habe; ein Proxy Ich habe versucht, diese zusätzliche Schicht von der Mitte zu vermeiden, um die Vorzüge von LINQToSQL-Objekten zu erhalten, die bindbar sind, aber es sieht so aus, als gäbe es keine anderen Optionen als LinqToSql hinter einem Proxy zu verstecken, so dass die benutzerdefinierte Logik hinzugefügt werden kann. –

0

Wenn Sie doppelte Benutzernamen in Ihrer Datenbank vermeiden wollen, warum nicht einen eindeutigen Index auf diesem Gebiet setzen?

+0

kann und habe ich eigentlich schon aber das oben erwähnte Szenario war nur ein Beispiel über die Frage, wie man mit einer benutzerdefinierten Logik umgehen soll. –