Ok, sono andato fino in fondo nella tana del coniglio su questo, ma credo di avere una soluzione piuttosto fresco:
In primo luogo, aggiungere un gestore di eventi al vostro contesto dati che raccoglierà tutti i post -Salvia i segnali e nascondi il metodo Dispose
in modo che possiamo chiamare l'evento giusto prima di sbarazzarci. (Si noti che uso la parola al posto di override
new
. Questo rende chiamando possibile l'evento.)
partial class MyDataContext
{
internal delegate void PostSaveHandler();
internal event PostSaveHandler PostSave;
// This method hides the underlying Dispose because we need to call PostSave.
public new void Dispose(bool disposing)
{
// Obviously necessary error handling omitted for brevity's sake
PostSave();
base.Dispose(disposing);
}
}
Avanti, scrivere un T4 Template che esamini il fascicolo dbml
che LINQ to SQL genera per voi.
<#
var dbml = XDocument.Load(@"MyDataContext.dbml");
var name = XName.Get("Type", "http://schemas.microsoft.com/linqtosql/dbml/2007");
var tables = from t in dbml.Descendants(name) select t.Attribute("Name").Value;
foreach(var table in tables)
{
#>
...
Per ogni tabella nel database (e quindi ogni classe parziale), aggiungere al parziale con i seguenti metodi.
public partial class Foo
{
internal void OnInsert(MyDataContext db) {
PreInsert();
db.PostSave += delegate { PostInsert(); };
}
internal void OnUpdate(MyDataContext db) {
PreUpdate();
db.PostSave += delegate { PostUpdate(); };
}
internal void OnDelete(MyDataContext db) {
PreDelete();
db.PostSave += delegate { PostDelete(); };
}
partial void PreInsert();
partial void PostInsert();
partial void PreUpdate();
partial void PostUpdate();
partial void PreDelete();
partial void PostDelete();
}
// repeat for all tables
Aggiungere un altro partial MyDataContext
tramite T4. Questo aggiungerà definizioni ai metodi parziali forniti da Linq a SQL (come menzionato da Merritt).
public partial class MyDataContext
{
// Add these three partial methods for each table
partial void InsertFoo(Foo foo)
{
foo.OnInsert(this);
ExecuteDynamicInsert(foo);
}
partial void UpdateFoo(Foo foo)
{
foo.OnUpdate(this);
ExecuteDynamicUpdate(foo);
}
partial void DeleteFoo(Foo foo)
{
foo.OnDelete(this);
ExecuteDynamicDelete(foo);
}
// ...
}
Nascondere questi file in un posto sicuro, in modo che nessuno provi a fare confusione con loro.
Il quadro dei segnali è impostato. Ora puoi scrivere i tuoi segnali. Mettete questi sia in Foo.cs
o tutti insieme in un file Signals.cs
:
partial class Foo
{
partial void PostInsert()
{
EventLog.AddEvent(EventType.FooInserted, this);
}
}
Questo è un po 'complessa, quindi se qualcosa non ha senso, si prega di lasciare un commento e farò del mio meglio per affrontarlo.