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

发布于 2024-07-30 13:04:39 字数 1199 浏览 4 评论 0原文

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

父级与子级有关联,但似乎我不能在 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() 函数的单次调用来自动插入子记录。

Using LINQ-to-SQL, I would like to automatically create child records when inserting the parent entity. Basically, mimicking how an SQL Insert trigger would work, but in-code so that some additional processing can be done.

The parent has an association to the child, but it seems that I cannot simply add new child records during the DataContext's SubmitChanges().

For example,

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);
        }
    }
}

This would be ideal, but unfortunately the newly created Child record is not inserted to the database. Makes sense, since the DataContext has a list of objects/statements and probably doesn't like new items being added in the middle of it.

Similarly, intercepting the partial void InsertParent(Parent instance) function in the DataContext and attempting to add the Child record yields the same result - no errors, but nothing added to the database.

Is there any way to get this sort of behaviour without adding code to the presentation layer?

Update:
Both the OnValidate() and InsertParent() functions are called from the DataContext's SubmitChanges() function. I suspect this is the inherent difficulty with what I'm trying to do - the DataContext will not allow additional objects to be inserted (e.g. through InsertOnSubmit()) while it is in the process of submitting the existing changes to the database.

Ideally I would like to keep everything under one Transaction so that, if any errors occur during the insert/update, nothing is actually changed in the database. Hence my attempts to mimic the SQL Trigger functionality, allowing the child records to be automatically inserted through a single call to the DataContext's SubmitChanges() function.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

御弟哥哥 2024-08-06 13:04:39

如果您希望它在保存之前发生; 您可以重写SubmitChanges,并调用GetChangeSet()来获取待处理的更改。 查找您感兴趣的内容(例如,delta.Inserts.OfType(),并进行所需的更改。

然后调用 base.提交更改(...)

。 595258">这是一个相关示例,处理删除。

If you want it to happen just before it is saved; you can override SubmitChanges, and call GetChangeSet() to get the pending changes. Look for the things you are interested in (for example, delta.Inserts.OfType<Customer>(), and make your required changes.

Then call base.SubmitChanges(...).

Here's a related example, handling deletes.

Oo萌小芽oO 2024-08-06 13:04:39

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

您确实可以通过在 DataContext 中实现 InsertParent 来访问它,因此我会采用该路线(并使用 InsertOnSubmit 而不是 Add,课程)。

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

The Add method only sets up a link between the two objects: it doesn't mark the added item for insertion into the database. For that, you need call InsertOnSubmit on the Table<Child> instance contained within your DataContext. The trouble, of course, is that there's no innate way to access your DataContext from the method you describe.

You do have access to it by implementing InsertParent in your DataContext, so I'd go that route (and use InsertOnSubmit instead of Add, of course).

EDITED I assumed that the partial method InsertParent would be called by the DataContext at some point, but in looking at my own code that method appears to be defined but never referenced by the generated class. So what's the use, I wonder?

流年已逝 2024-08-06 13:04:39

在 linq to sql 中,您可以通过为 dbml 文件创建部分类,然后插入部分方法来创建“触发器”。 这是一个不会执行任何操作的示例,因为它调用了内置删除。

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

In linq to sql you make a "trigger" by making a partial class to the dbml file, and then inserting a partial method. Here is an example that wouldn't do anything because it calls the build-in deletion.

partial void DeleteMyTable(MyTable instance)
{
    //custom code here
    ExecuteDynamicDelete(instance);
    //or here :-)
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文