EF 6代码优先与自定义存储过程

edu*_*glz 9 c# sql-server asp.net-mvc stored-procedures entity-framework

我正在使用Code-First方法创建一个MVC 5应用程序,但我还在SQL Server数据库上创建了一些存储过程,有没有办法在创建数据库时在c#中生成这些存储过程,可能是通过执行sql脚本,如果是这样我应该在哪里这样做?

Chr*_*ang 5

我会使用代码迁移。

从 Nuget 包管理器中,您可以通过键入以下内容来设置空白迁移

add-migration AddMyStoredProcedure
Run Code Online (Sandbox Code Playgroud)

这应该生成一个空类,如下所示

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

    public override void Down()
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

您所需要做的就是像这样添加存储过程(请记住在 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");
    }
}
Run Code Online (Sandbox Code Playgroud)

最后更新你的数据库

update-database
Run Code Online (Sandbox Code Playgroud)


Mon*_*nah 5

迟到的答案,但也许有人会得到这样的问题的答案

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

  1. sql在您的项目中创建一个文件,以删除您拥有的所有视图函数过程(如果存在),drop.sql例如调用它。
  2. 为项目中的每个viewfunction和创建stored procedure一个单独的文件。sql
  3. 将所有sql文件标记为Embedded Resource,右键单击该文件,然后单击属性,然后单击“构建操作”,选择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]
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

迁移种子法

我假设您在项目的Migrations文件夹内的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"));
}
Run Code Online (Sandbox Code Playgroud)

最后是Load方法

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

该解决方案的好处是它每次都会运行,并且您将确保是否存在任何问题(例如,一段时间后您更改了字段名称或删除了视图、函数或过程中使用的表)如果不记得必须更新程序,则会出现错误,如果启用了自动迁移,则可以修复)。

希望对你有帮助


Elv*_*ves 0

您可能需要使用迁移来处理它。可以找到一个好看的解决方案/sf/answers/1062033031/。使用资源,但我确信如果您不想沿着资源路径走下去,您可以以相同的方式从 .sql 文件中读取文本。