Создавать хранимые процедуры с использованием кода Entity Framework?

Я использую Entity Framework Code First в моем текущем проекте. База данных состоит из множества таблиц, множества представлений и множества функций. Я могу создавать таблицы, используя Entity Framework Code First. Но я не могу найти способ создания хранимых процедур, используя Entity Framework Code First. Я знаю, что стратегия Database-First выполнит мое требование, и все работает хорошо, но я не хочу использовать стратегию Database-First в моем существующем коде проекта.

Пожалуйста, помогите мне кто-нибудь, каковы лучшие способы создания хранимых процедур с использованием стратегии Entity Framework Code First?

Пожалуйста, помогите мне с этим, спасибо.

3 ответа

Вместо использования StringBuilder вы можете использовать существующие методы EF

public override void Up() 
{
  CreateStoredProcedure(
    "MyStoredProcedure",
    p => new
    {
        id = p.Int()
    },
    @"SELECT some-data FROM my-table WHERE id = @id"
  );
}

public override void Down() 
{
  DropStoredProcedure("MyStoredProcedure");
}

С Code First вы всегда делаете Миграции. Миграции наследуются от объекта DbMigration, который имеет очень полезный метод:

DbMigration.Sql (строка)

Вот шаги:

1) Откройте консоль диспетчера пакетов из диспетчера пакетов NuGet

2) Введите add-igration CreateHelloWorldStoredProcedureExample

3) Visual Studio покажет вам новый класс с двумя пустыми методами: вверх и вниз

4) В методе Up напишите свой код, вот пример

 public override void Up()
 {
        StringBuilder storedProcedureCode = new StringBuilder();

        storedProcedureCode.Append("CREATE PROCEDURE dbo.HelloWorld" + Environment.NewLine);
        storedProcedureCode.Append("AS" + Environment.NewLine);
        storedProcedureCode.Append("BEGIN" + Environment.NewLine);
        storedProcedureCode.Append(@"SELECT 'Hello World'" + Environment.NewLine);
        storedProcedureCode.Append("END" + Environment.NewLine);

        this.Sql(storedProcedureCode.ToString());
}

В то время как в методе Дауна:

public override void Down()
    {
        this.Sql("DROP PROCEDURE dbo.HelloWorld ");
    }

После этого просто запустите update-database и все!

Примечание. Если вы используете SQL Server, избегайте использования предложения GO.

Если вы используете EF Core 2.1, вы можете создать хранимую процедуру следующим образом:

public partial class AddStoredProcedure : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.Sql(@"your create procedure statement");
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.Sql(@"your drop procedure statement");
    }
}

Я написал следующие методы расширения, чтобы упростить создание или удаление процедуры. По сути, метод расширения SqlFromFile используется для чтения из файла, который был добавлен в проект с параметром "Копировать в выходной каталог", установленным на "Копировать, если новее". Файл считывается в динамический оператор sql из-за проблем, которые возникли у dotnet ef при создании сценария миграции.

В дополнение к методам расширения для процедуры решение может быть расширено для использования с пользовательскими функциями, представлениями или другими объектами базы данных.

    public static void SqlFromFile(this MigrationBuilder builder, string filename)
    {
        if (string.IsNullOrEmpty(filename))
            throw new ArgumentException("Required parameter is missing.", nameof(filename));

        FileInfo assemblyInfo = new FileInfo(Assembly.GetExecutingAssembly().Location);
        string fullPath = Path.Combine(assemblyInfo.Directory.FullName, filename);

        if (File.Exists(fullPath))
        {
            string sql = File.ReadAllText(fullPath);
            string lf = Environment.NewLine; // For compilation on Windows or Linux
            builder.Sql($"EXEC sp_executesql N'{lf}{sql.Replace("'", "''")}{lf}'");
        }
        else
        {
            throw new FileNotFoundException("File not found.", fullPath);
        }
    }

    public static void CreateProcedure(this MigrationBuilder builder, string name, string schema, string filename, bool dropIfExists = true)
    {
        if (string.IsNullOrEmpty(name))
            throw new ArgumentException("Required parameter is missing.", nameof(name));

        if (string.IsNullOrEmpty(filename))
            throw new ArgumentException("Required parameter is missing.", nameof(filename));

        if (dropIfExists) DropProcedure(builder, name, schema);

        SqlFromFile(builder, filename);
    }

    public static void DropProcedure(this MigrationBuilder builder, string name, string schema = null)
    {
        if (string.IsNullOrEmpty(name))
            throw new ArgumentException("Required parameter is missing.", nameof(name));

        if (string.IsNullOrEmpty(schema))
            schema = "dbo";

        builder.Sql($"IF OBJECT_ID('[{schema}].[{name}]', 'P') IS NOT NULL DROP PROCEDURE [{schema}].[{name}]");
    }
Другие вопросы по тегам