さて、私はこれでうさぎの穴を完全に通り抜けました、しかし私はかなりクールな解決策を持っていると思います:
まず、保存後のすべてのシグナルを収集し、Dispose
メソッドを非表示にするイベントハンドラーをデータコンテキストに追加して、破棄する直前にイベントを呼び出すことができるようにします。new
(代わりにキーワードを使用することに注意してくださいoverride
。これにより、イベントの呼び出しが可能になります。)
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);
}
}
次に、LinqtoSqlが生成するファイルを検査するT4テンプレートを作成します。dbml
<#
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)
{
#>
...
データベース内の各テーブル(したがって、各パーシャルクラス)について、次のメソッドを使用してパーシャルに追加します。
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
partial MyDataContext
また、 T4を介して別のものを追加します。これにより、Linq to SQLが提供する部分メソッドに定義が追加されます(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);
}
// ...
}
それらのファイルを安全な場所に隠して、だれもそれらを台無しにしようとしないようにします。
シグナルフレームワークが設定されています。これで、信号を書き込むことができます。これらをファイルに入れるか、Foo.cs
すべてまとめてSignals.cs
ファイルに入れます。
partial class Foo
{
partial void PostInsert()
{
EventLog.AddEvent(EventType.FooInserted, this);
}
}
これは少し複雑なので、意味がわからない場合はコメントを残してください。できる限り対処します。