Имитация триггера вставки SQL с помощью LINQ-to-SQL - PullRequest
6 голосов
/ 06 августа 2009

Используя LINQ-to-SQL, я хотел бы автоматически создавать дочерние записи при вставке родительской сущности. По сути, имитирует работу триггера SQL Insert, но внутри кода, чтобы можно было выполнить дополнительную обработку.

Родитель связан с дочерним элементом, но, похоже, я не могу просто добавить новые дочерние записи во время SubmitChanges().

DataContext.

Например,

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 имеет список объектов / операторов и, вероятно, не любит добавление новых элементов в середине.

Аналогично, перехват функции partial void InsertParent(Parent instance) в DataContext и попытка добавить запись Child дает тот же результат - никаких ошибок, но ничего не добавлено в базу данных.

Есть ли способ получить такое поведение без добавления кода на уровень представления?

Обновление: Обе функции OnValidate() и InsertParent() вызываются из функции DataContext SubmitChanges(). Я подозреваю, что это связано с тем, что я пытаюсь сделать - DataContext не позволит вставлять дополнительные объекты (например, через InsertOnSubmit()), пока он находится в процессе отправки существующих изменений в базу данных.

В идеале я хотел бы сохранить все в одной транзакции, чтобы в случае каких-либо ошибок во время вставки / обновления ничего не изменилось в базе данных. Поэтому я пытаюсь имитировать функциональность SQL Trigger, позволяя автоматически вставлять дочерние записи через один вызов функции DataContext SubmitChanges().

Ответы [ 3 ]

6 голосов
/ 08 августа 2009

Если вы хотите, чтобы это произошло непосредственно перед сохранением; Вы можете переопределить SubmitChanges и вызвать GetChangeSet(), чтобы получить ожидающие изменения. Ищите вещи, которые вас интересуют (например, delta.Inserts.OfType<Customer>(), и внесите необходимые изменения.

Тогда вызов base.SubmitChanges(...).

Вот связанный пример , обработка удалений.

2 голосов
/ 06 августа 2009

Метод Add только устанавливает связь между двумя объектами: он не помечает добавленный элемент для вставки в базу данных. Для этого вам нужно вызвать InsertOnSubmit для экземпляра Table<Child>, содержащегося в вашем DataContext. Проблема, конечно, в том, что нет никакого врожденного способа получить доступ к вашему DataContext из метода, который вы описываете.

У вас есть доступ к нему путем реализации InsertParent в вашем DataContext, поэтому я бы пошел по этому пути (и использовал бы InsertOnSubmit вместо Add, конечно).

РЕДАКТИРОВАНИЕ Я предполагал, что частичный метод InsertParent будет вызван DataContext в некоторый момент, но, глядя на мой собственный код, этот метод, кажется, определен, но никогда не ссылается на сгенерированный учебный класс. Интересно, а какая польза от этого?

0 голосов
/ 19 февраля 2015

В linq to sql вы делаете «триггер», создавая частичный класс в файл dbml, а затем вставляя частичный метод. Вот пример, который ничего не делает, потому что вызывает удаление встроенной функции.

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