gpt4 book ai didi

asp.net-mvc - Linq to Sql 中的信号?

转载 作者:行者123 更新时间:2023-12-02 04:47:42 25 4
gpt4 key购买 nike

有谁知道有什么方法可以做类似 Django's signals 的事情吗?使用 LINQ to SQL?

我试图记录何时插入新行以及何时更新某些列,所以我真的只想 pre_savepost_save信号。

我可以通过使用像 OnFooIDChanging() 这样定义的部分来对某些模型执行此操作。和OnFooIDChanged() (其中 FooID 是主键),但这不适用于主键不是身份或由代码设置的模型。

对于这些,我可能会使用 OnValidate() ,但这只是pre_save ,这使得处理数据库变得困难,因为 OnValidate()DBContext.SubmitChanges() 调用,这当然不允许第二个 SubmitChanges()从内部调用,使 post_save据我所知基本上不可能。

最佳答案

好吧,我已经彻底陷入了这个问题,但我认为我有一个非常酷的解决方案:

首先,向您的数据上下文添加一个事件处理程序,该处理程序将收集所有保存后信号并隐藏 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它检查 Linq to Sql 为您生成的 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

还通过 T4 添加另一个部分 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);
}
}

这有点复杂,所以如果有任何不明白的地方,请发表评论,我会尽力解决它。

关于asp.net-mvc - Linq to Sql 中的信号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1009801/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com