ExecuteSqlCommand на семя для создания триггера с EntityFramework выбрасывает SqlException

c# entity-framework entity-framework-6 sql

Вопрос

Я пытаюсь создать триггер для обновления номера документа с помощью метода Seed () в ContextInitalizer с Entity Framework 6.0.2 и .Net 4. Когда я запускаю SQL отдельно, создается триггер; при инициализации контекста генерируется исключение SqlException:

Неправильный синтаксис рядом с словом «TRIGGER».

Мой скрипт sql, содержащийся в /SQL/CreateOrderNumber.sql, - это:

CREATE TRIGGER [dbo].[CreateOrderNum] 
ON [dbo].[Orders] 
AFTER INSERT AS 
BEGIN 
SET NOCOUNT ON; 
DECLARE @MaximumNumber int; 
SET @MaximumNumber = (SELECT ISNULL(MAX(RIGHT([DocNumber],6)),0) FROM [Orders]); 
UPDATE [Orders] 
SET [DocNumber] = 'ORD-' + RIGHT('000000' + CAST((@MaximumNumber + 1) AS VARCHAR(8)), 6) 
FROM inserted 
WHERE [Orders].[Id] = inserted.Id; 
END

И следующий код воссоздает ошибку:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Data.SqlClient;
using System.IO;
using System.Reflection;

namespace TriggerCreationTest
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create the context, add an order, and save...
            using (var context = new Context())
            {
                context.Orders.Add(new Order());
                context.SaveChanges();
            }
        }
    }

    public class Context : DbContext
    {
        public Context() : base("TestDatabase")
        {
            Database.SetInitializer<Context>(new ContextInitializer());
        }

        public DbSet<Order> Orders { get; set; }
    }

    public class ContextInitializer : DropCreateDatabaseAlways<Context>
    {
        protected override void Seed(Context context)
        {
            // Get the file and read the text
            var execPath = Assembly.GetExecutingAssembly().Location;
            var createOrderNumPath = Path.Combine(execPath, @"..\SQL\CreateOrderNumber.sql");
            var sql = File.ReadAllText(createOrderNumPath);

            // Execute the CREATE TRIGGER on the database.
            var emptyparams = new SqlParameter[] { new SqlParameter() };
            context.Database.ExecuteSqlCommand(sql, emptyparams);

            base.Seed(context);
        }
    }

    public class Order
    {
        public Order() { }

        [Key]
        public int Id { get; set; }
        [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
        public string DocNumber { get; set; }
    }
}

На этом этапе я попытался переписать сценарий CREATE TRIGGER в соответствии с различными источниками в Интернете, но не успел его запустить.

Принятый ответ

Поработав над этим и обратив внимание на другие проекты, я вернулся, чтобы увидеть, изменится ли обновление до EntityFramework 6.1.0. Это не так!

Однако я нашел свою ошибку. Я передавал пустой SqlParameter в SqlCommand, и это приводило к его провалу. Если вместо этого я изменяю массив SqlParameter, чтобы не содержать элементов:

public class ContextInitializer : DropCreateDatabaseAlways<Context> 
{
     protected override void Seed(Context context)
     {
         // Get the file and read the text
         var execPath = Assembly.GetExecutingAssembly().Location;
         var createOrderNumPath = Path.Combine(execPath, @"..\SQL\CreateOrderNumber.sql");
         var sql = File.ReadAllText(createOrderNumPath);

         // Execute the CREATE TRIGGER on the database.
         // CHANGE emptyparams TO CONTAIN NO ELEMENTS
         var emptyparams = new SqlParameter[] { };
         context.Database.ExecuteSqlCommand(sql, emptyparams);

         base.Seed(context);
     }

}

Команда выполняется так, как ожидалось, и запускается триггер.




Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему