EF 4.1 code-first добавление триггера в таблицу

Каков наилучший способ добавить триггер в таблицу, созданную с помощью подхода «сначала код» с помощью EF 4.1?

Я рассматриваю способ выполнения пользовательского SQL-запроса либо в OnModelCreating, либо при инициализации контекста Db.

Есть ли идея получше?


person Dmitri    schedule 06.05.2011    source источник


Ответы (2)


Использование пользовательского инициализатора, который будет выполнять команду CREATE TRIGGER SQL, является единственным вариантом, если вы хотите, чтобы EF создал для вас триггер (такой же код, как здесь). Также не забудьте включить SET NOCOUNT ON в начало кода триггера.

Но есть более сложная проблема, связанная с логикой триггера. Если вам нужен триггер, который будет изменять данные, передаваемые в базу данных, вы должны понимать, что изменения, сделанные триггером, не будут отражены в вашем текущем контексте. Контекст по-прежнему будет знать только объект с данными, которые вы передали в базу данных. Обычно это решается установкой свойств, измененных триггером, как DatabaseGeneratedOption.Computed для обновления или DatabaseGeneratedOption.Identity для вставки. В таком случае вы не можете изменять свойства в своем приложении, и они должны быть изменены в базе данных. EF гарантирует, что эти свойства будут выбраны после изменения и переданы сущности. Проблема в том, что это не работает с кодом вперед.

person Ladislav Mrnka    schedule 06.05.2011
comment
в моем текущем сценарии мне нужно обновить столбец DateModified в одной из таблиц. значение DateModified не будет использоваться текущим контекстом. - person Dmitri; 06.05.2011
comment
на самом деле думая об этом, поскольку объекты POCO отслеживаются контекстом, могу ли я использовать это для обновления моей временной метки? - person Dmitri; 06.05.2011
comment
DateModified не будет использоваться контекстом не соответствует подходу code-first, при котором вы определяете только те столбцы, которые используются контекстом. - person Ladislav Mrnka; 06.05.2011
comment
Конечно, вы можете изменить DateModified в контексте перед сохранением изменений, переопределив SaveChanges итерацию всех измененных объектов и установку поля. - person Ladislav Mrnka; 06.05.2011
comment
DateModified будет использоваться, но не в текущем контексте. спасибо за всю информацию! - person Dmitri; 06.05.2011

Я не совсем понимаю, что вы имеете в виду. Если вам нужен фактический триггер SQL для таблицы, я бы создал триггер, как обычно, в SQL. Если вы имеете в виду, что хотите, чтобы в вашем коде происходила какая-то обработка/обновление всякий раз, когда изменяется один из ваших наборов сущностей, то я думаю, вы хотели бы сделать собственный метод, который будет вызываться всякий раз, когда этот набор сущностей обновляется.

person AllenG    schedule 06.05.2011
comment
Мне нужен настоящий триггер на столе. Если я создам его непосредственно в SQL, он будет потерян из-за этого DropCreateDatabaseIfModelChanges. - person Dmitri; 06.05.2011
comment
Если требуется наличие триггера SQL, вы всегда можете создать сценарий и просто запустить его при повторном создании таблиц. Это немного противно, однако. Ладислав делает хорошее замечание: каждый раз, когда срабатывает ваш триггер, вам нужно обновлять свой контекст. Если это можно сделать в коде, я думаю, вы избавите себя от головной боли. - person AllenG; 06.05.2011
comment
В этом нет никакого смысла... Почему бы не использовать SQL вместо вторичного вызова БД из кода? Это меньше кода для написания и выполнения, а также заставляет SQL делать то, что он должен делать, то есть триггеры. Не говоря уже о том, что на один вызов БД меньше. - person IyaTaisho; 27.02.2013