好吧,我已经完全消失了下来就这一个兔子洞,但我认为我有一个相当酷的解决方案:
首先,添加事件处理程序到您的数据背景下,将收集所有的帖子 - 保存信号并隐藏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 Template是考察dbml
文件Sql的Linq为您生成。
<#
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
还通过T4添加另一个partial MyDataContext
。这将为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);
}
}
这是一个有点复杂,所以如果有什么是没有意义的,请留言,我会尽我所能来解决它。