使用LINQ-to-SQL模仿SQL插入触发器

时间:2009-08-06 18:15:14

标签: linq linq-to-sql datacontext triggers submitchanges

使用LINQ-to-SQL,我想在插入父实体时自动创建子记录。基本上,模仿SQL Insert触发器的工作方式,但是在代码中,以便可以进行一些额外的处理。

父级与子级有关联,但似乎我不能简单地在DataContext的SubmitChanges()期间添加新的子记录。

例如,

public partial class Parent 
{
    partial void OnValidate(System.Data.Linq.ChangeAction action)
    {
        if(action == System.Data.Linq.ChangeAction.Insert)
        {
            Child c = new Child();
            ... set properties ...
            this.Childs.Add(c);
        }
    }
}

这是理想的,但不幸的是,新创建的Child记录未插入数据库。有道理,因为DataContext有一个对象/语句列表,可能不喜欢在它的中间添加新项目。

同样,拦截DataContext中的partial void InsertParent(Parent instance)函数并尝试添加Child记录会产生相同的结果 - 没有错误,但没有添加到数据库中。

在没有向表示层添加代码的情况下,有没有办法获得这种行为?

更新 OnValidate()InsertParent()函数都是从DataContext的SubmitChanges()函数中调用的。我怀疑这是我正在尝试做的事情的固有困难 - 在将现有更改提交到数据库的过程中,DataContext将不允许插入其他对象(例如通过InsertOnSubmit())。

理想情况下,我希望将所有内容保留在一个事务处理中,以便在插入/更新期间发生任何错误时,数据库中实际上没有任何更改。因此,我试图模仿SQL触发器功能,允许通过对DataContext的SubmitChanges()函数的单次调用自动插入子记录。

3 个答案:

答案 0 :(得分:6)

如果你希望它在保存之前发生;您可以覆盖SubmitChanges,并致电GetChangeSet()以获取待处理的更改。查找您感兴趣的内容(例如delta.Inserts.OfType<Customer>(),并进行必要的更改。

然后致电base.SubmitChanges(...)

Here's a related example,处理删除。

答案 1 :(得分:2)

Add方法仅在两个对象之间建立链接:它不标记添加的项目以插入数据库。为此,您需要在DataContext中包含的InsertOnSubmit实例上调用Table<Child>。当然,问题在于没有从您描述的方法访问DataContext的固有方法。

您可以通过在DataContext中实施InsertParent来访问它,因此我会走这条路线(当然使用InsertOnSubmit代替Add

已编辑我认为InsertParent会在某个时刻调用部分方法DataContext,但在查看我自己的代码时,该方法似乎已定义但从未被生成的类引用。那我有什么用呢?

答案 2 :(得分:0)

在linq to sql中,通过对dbml文件创建一个部分类,然后插入一个部分方法来创建一个“触发器”。这是一个不会做任何事情的例子,因为它调用了内置删除。

partial void DeleteMyTable(MyTable instance)
{
    //custom code here
    ExecuteDynamicDelete(instance);
    //or here :-)
}