好的,我已经完全放弃了这个,但我认为我有一个非常酷的解决方案:
首先,将事件处理程序添加到您的数据上下文中,该处理程序将收集所有保存后信号并隐藏该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);
}
}
接下来,编写一个T4 模板来检查dbml
Linq to Sql 为您生成的文件。
<#
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);
}
}
这有点复杂,所以如果有什么不明白的地方,请发表评论,我会尽力解决它。