Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 代码优先迁移和存储过程_Sql Server_Asp.net Mvc_Entity Framework_Code First - Fatal编程技术网

Sql server 代码优先迁移和存储过程

Sql server 代码优先迁移和存储过程,sql-server,asp.net-mvc,entity-framework,code-first,Sql Server,Asp.net Mvc,Entity Framework,Code First,我刚刚创建了一个数据库并完成了我的第一次迁移,只是添加了一个简单的表。现在我想添加一些存储过程,我刚刚通过编写sql并在ManagementStudio中执行添加的存储过程。但是,如果可能的话,我希望在迁移中包含这些存储过程,以便保存它们,并且可以对它们运行Up或Down方法。这可能吗?如果可能,需要使用什么语法?还是我只需要使用Management Studio添加/编辑/删除它们?我已经这样做了 在当前迁移类中- public partial class MyMigration : DbMi

我刚刚创建了一个数据库并完成了我的第一次迁移,只是添加了一个简单的表。现在我想添加一些存储过程,我刚刚通过编写sql并在ManagementStudio中执行添加的存储过程。但是,如果可能的话,我希望在迁移中包含这些存储过程,以便保存它们,并且可以对它们运行Up或Down方法。这可能吗?如果可能,需要使用什么语法?还是我只需要使用Management Studio添加/编辑/删除它们?

我已经这样做了

在当前迁移类中-

public partial class MyMigration : DbMigration
{
    public override void Up()
    {
        ... other table creation logic

        // This command executes the SQL you have written
        // to create the stored procedures
        Sql(InstallScript);

        // or, to alter stored procedures
        Sql(AlterScript);
    }

    public override void Down()
    {
        ... other table removal logic

        // This command executes the SQL you have written
        // to drop the stored procedures
        Sql(UninstallScript);

        // or, to rollback stored procedures
        Sql(RollbackScript);
    }

    private const string InstallScript = @"
        CREATE PROCEDURE [dbo].[MyProcedure]
        ... SP logic here ...
    ";

    private const string UninstallScript = @"
        DROP PROCEDURE [dbo].[MyProcedure];
    ";

    // or for alters
    private const string AlterScript = @"
        ALTER PROCEDURE [dbo].[AnotherProcedure]
        ... Newer SP logic here ...
    ";

    private const string RollbackScript = @"
        ALTER PROCEDURE [dbo].[AnotherProcedure]
        ... Previous / Old SP logic here ...
    ";
}
我使用的是EF6,DbMigration类提供了创建/更改/删除存储过程的方法

创建一个新的存储过程

public partial class MyFirstMigration : DbMigration
{
    public override void Up()
    {
        // Create a new store procedure
        CreateStoredProcedure("dbo.DequeueMessages"
        // These are stored procedure parameters
        , c => new{                
            MessageCount = c.Int()
        },
        // Here is the stored procedure body
        @"
        SET NOCOUNT ON;
        SELECT TOP (@MessageCount)
            *
        FROM
            dbo.MyTable;
        ");
    }

    public override void Down()
    {
        // Delete the stored procedure
        DropStoredProcedure("dbo.DequeueMessages");                
    }
}
public partial class MySecondMigration : DbMigration
{
    public override void Up()
    {
        // Modify an existing stored procedure
        AlterStoredProcedure("dbo.DequeueMessages"
        // These are new stored procedure parameters
        , c => new{                
            MessageCount = c.Int(),
            StatusId = c.Int()
        },
        // Here is the new stored procedure body
        @"
        SET NOCOUNT ON;
        SELECT TOP (@MessageCount)
            *
        FROM
            dbo.MyTable
        WHERE
            StatusId = @StatusId;
        ");
    }

    public override void Down()
    {
        // Rollback to the previous stored procedure
        // Modify an existing stored procedure
        AlterStoredProcedure("dbo.DequeueMessages"
        // These are old stored procedure parameters
        , c => new{                
            MessageCount = c.Int()
        },
        // Here is the old stored procedure body
        @"
        SET NOCOUNT ON;
        SELECT TOP (@MessageCount)
            *
        FROM
            dbo.MyTable;
        ");              
    }
}
修改存储过程

public partial class MyFirstMigration : DbMigration
{
    public override void Up()
    {
        // Create a new store procedure
        CreateStoredProcedure("dbo.DequeueMessages"
        // These are stored procedure parameters
        , c => new{                
            MessageCount = c.Int()
        },
        // Here is the stored procedure body
        @"
        SET NOCOUNT ON;
        SELECT TOP (@MessageCount)
            *
        FROM
            dbo.MyTable;
        ");
    }

    public override void Down()
    {
        // Delete the stored procedure
        DropStoredProcedure("dbo.DequeueMessages");                
    }
}
public partial class MySecondMigration : DbMigration
{
    public override void Up()
    {
        // Modify an existing stored procedure
        AlterStoredProcedure("dbo.DequeueMessages"
        // These are new stored procedure parameters
        , c => new{                
            MessageCount = c.Int(),
            StatusId = c.Int()
        },
        // Here is the new stored procedure body
        @"
        SET NOCOUNT ON;
        SELECT TOP (@MessageCount)
            *
        FROM
            dbo.MyTable
        WHERE
            StatusId = @StatusId;
        ");
    }

    public override void Down()
    {
        // Rollback to the previous stored procedure
        // Modify an existing stored procedure
        AlterStoredProcedure("dbo.DequeueMessages"
        // These are old stored procedure parameters
        , c => new{                
            MessageCount = c.Int()
        },
        // Here is the old stored procedure body
        @"
        SET NOCOUNT ON;
        SELECT TOP (@MessageCount)
            *
        FROM
            dbo.MyTable;
        ");              
    }
}
因此,当您在SQL server中查看/修改SP时,它会显示ALTER PROCEDURE


我将尝试提供一个不同的视角,因为在C字符串中包含SQL代码不是很吸引人,人们应该期望在提供intellisense的工具(例如SSMS)中更改此类脚本

以下解决方案在ASP.NET Core 2.0 Web API项目中实现

使用任何方便的工具在开发数据库中维护程序

生成过程脚本:

public class ProcedureItemMetadata
{
    /// <summary>
    /// SQL server side object identifier
    /// </summary>
    [Key]
    public int ObjectId { get; set; }

    /// <summary>
    /// schema name
    /// </summary>
    public string SchemaName { get; set; }

    /// <summary>
    /// procedure name
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// procedure body
    /// </summary>
    public string Definition { get; set; }
}


public string GetProceduresScript()
{
   var query = Context.ProcedureItemMetadata.AsNoTracking().FromSql(@"
      SELECT ao.object_id as ObjectId, SCHEMA_NAME(ao.schema_id) as SchemaName, ao.name, sm.definition
      FROM sys.all_objects ao 
      JOIN sys.sql_modules sm ON sm.object_id = ao.object_id
      WHERE ao.type = 'P'
         and execute_as_principal_id IS NULL
      order by 1;");

      var list = query.ToList();
      string text = string.Join($" {Base.Constants.General.ScriptGeneratorSeparator}\n", list.Select(p => p.Definition));

      // replace create with create or alter
      string replaced = Regex.Replace(text,
         @"(?<create>CREATE\s+PROCEDURE\s+)",
         "CREATE OR ALTER PROCEDURE ", 
         RegexOptions.IgnoreCase);

      return replaced;
}

这种方法允许管理在迁移过程中不易维护的任何脚本。

可能的重复如果您正在更改过程,因为它是在以前的迁移中创建的,然后需要继续执行,该怎么办?你不能只是放弃这个过程,它必须回到它的原始状态,不管这个过程以前是什么样子。。。