EF 6代码首先使用自定义存储过程

本文关键字:自定义 存储过程 代码 EF | 更新日期: 2023-09-27 18:00:06

我正在用代码优先的方法创建一个MVC 5应用程序,但我也在SQL Server数据库上创建了一些存储过程,在创建数据库时,有没有一种方法可以在c#中生成这些存储过程,可能是通过执行SQL脚本,如果有,我应该在哪里执行?

EF 6代码首先使用自定义存储过程

我会使用代码迁移。

从Nuget软件包管理器,您可以通过键入来设置空白迁移

add-migration AddMyStoredProcedure

这应该会生成一个像这样的空类

public partial class AddMyStoredProcedure : DbMigration
{
    public override void Up()
    {
    }
    public override void Down()
    {
    }
}

您所需要做的就是像这样添加存储过程(记住在Down方法中删除存储过程,以防将来需要回滚迁移)。

    public partial class AddMyStoredProcedure : DbMigration
{
    public override void Up()
    {
        Sql(@"
            CREATE PROCEDURE dbo.GetMyAddress
            AS
            SELECT * FROM Person.Address");
    }
    public override void Down()
    {
        Sql("DROP PROCEDURE dbo.GetMyAddress");
    }
}

最后更新您的数据库

update-database

答案很晚,但也许有人会得到这样一个问题的答案

在我的项目中,我有很多viewsfunctionsstored procedures要处理,我使用的解决方案如下:

  1. 在项目中创建一个sql文件,以删除所有视图函数以及过程(如果它们存在),例如将其称为drop.sql
  2. 在项目中为每个viewfunctionstored procedure创建一个单独的sql文件
  3. 将所有sql文件标记为Embedded Resource,右键单击该文件,然后单击属性,然后单击Build Action,选择Embedded Resource

    YourFile.sql=>右键单击=>属性=>构建操作,选择嵌入式资源

  4. 在迁移种子函数中,使用ExecuteSqlCommand,您需要一个方法来读取这些文件以及下面所需的所有代码

drop.sql结构

-- your views
if object_id('dbo.[YourViewName1]') is not null
    drop view dbo.[YourViewName1]
if object_id('dbo.[YourViewName2]') is not null
    drop view dbo.[YourViewName2]
-- your functions 
if object_id('dbo.[Function1]') is not null
    drop function dbo.[Function1]
if object_id('dbo.[Function2]') is not null
    drop function dbo.[Function2]
-- your procedures
if object_id('dbo.[Procedure1]') is not null
    drop procedure dbo.[Procedure1]
if object_id('dbo.[Procedure2]') is not null
    drop procedure dbo.[Procedure2]

view.sql或function.sql或procedure.sql结构

create view View1 
as
  select Field1,Field2,...Fieldn
  from Table1
  inner join Table2 on Id1 = FId2  
  inner join TableN on IdI = IdJ

迁移种子方法

我假设您在sql文件夹中创建了所有sql文件在项目中的迁移文件夹内

protected override void Seed(YourContext context)
{
    context.Database
            .ExecuteSqlCommand(Load("YourProject.Migrations.Sql.drop.sql"));
    context.Database
            .ExecuteSqlCommand(Load("YourProject.Migrations.Sql.view1.sql"));
    context.Database
            .ExecuteSqlCommand(Load("YourProject.Migrations.Sql.view2.sql"));
    context.Database
            .ExecuteSqlCommand(Load("YourProject.Migrations.Sql.function1.sql"));
    context.Database
            .ExecuteSqlCommand(Load("YourProject.Migrations.Sql.function2.sql"));
    context.Database
            .ExecuteSqlCommand(Load("YourProject.Migrations.Sql.procedure1.sql"));
    context.Database
            .ExecuteSqlCommand(Load("YourProject.Migrations.Sql.procedure2.sql"));
}

最后是加载方法

private static string Load(string name)
{
    var assembly = Assembly.GetExecutingAssembly();
    using (Stream stream = assembly.GetManifestResourceStream(name))
    using (StreamReader reader = new StreamReader(stream))
    {
        string result = reader.ReadToEnd();
        return result;
    }
}

此解决方案的好处是它每次都会运行如果出现任何问题(例如,过了一段时间后更改了字段名,或者删除了视图中使用的表,或者函数或过程,如果不记住必须更新过程,则会出现错误,如果启用了自动迁移,则可以进行修复)。

希望这将帮助您

您可能需要使用迁移来处理它https://stackoverflow.com/a/15171900/119262.使用资源,但我相信,如果你不想沿着资源路径走下去,你可以用同样的方式从.sql文件中读取文本。