Создавать хранимые процедуры с использованием кода 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}]");
}