Sql server 代码优先迁移和存储过程
我刚刚创建了一个数据库并完成了我的第一次迁移,只是添加了一个简单的表。现在我想添加一些存储过程,我刚刚通过编写sql并在ManagementStudio中执行添加的存储过程。但是,如果可能的话,我希望在迁移中包含这些存储过程,以便保存它们,并且可以对它们运行Up或Down方法。这可能吗?如果可能,需要使用什么语法?还是我只需要使用Management Studio添加/编辑/删除它们?我已经这样做了 在当前迁移类中-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
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;
}
这种方法允许管理在迁移过程中不易维护的任何脚本。可能的重复如果您正在更改过程,因为它是在以前的迁移中创建的,然后需要继续执行,该怎么办?你不能只是放弃这个过程,它必须回到它的原始状态,不管这个过程以前是什么样子。。。