使用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()
函数的单次调用自动插入子记录。
答案 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 :-)
}