如何将存储过程映射到EF 6.1.1 Code First或更高版本?

时间:2014-08-03 05:10:17

标签: asp.net entity-framework

我一直在使用以下代码在C#控制器中执行存储过程。 db是我的EF数据库上下文。

var sql = @"dbo.sp_add_test  @CreatedBy,
                             @CreatedDate,
                             @TestId,
                             @TestStatusId";   
List<SqlParameter> parameterList = new List<SqlParameter>();
parameterList.Add(new SqlParameter("@CreatedBy", Int32.Parse(User.Identity.GetUserId()) ));
parameterList.Add(new SqlParameter("@CreatedDate", DateTime.UtcNow));
parameterList.Add(new SqlParameter("@TestId", testId));
parameterList.Add(new SqlParameter("@TestStatusId", 3));
SqlParameter[] parameters = parameterList.ToArray();


var test = await db.Database.SqlQuery<Test>(sql, parameters).FirstOrDefaultAsync();

我有建议&#34;为什么不在EF环境中映射您的SP?&#34;然而,当我对此进行研究时,我发现它很清楚如何做到这一点。首先,我看到那里有一个nuget包:

http://www.nuget.org/packages/EntityFramework.CodeFirstStoreFunctions/

但我不清楚。这是实现它的唯一方法还是有所改变。我看到互联网上的帖子和SO,但看起来最近情况正在发生变化,所以我认为这些可能已经过时了。

有人可以告诉我它现在是如何为EF 6.1.1完成的。请注意我正在寻找仅使用Microsoft工具执行此操作的官方方法。另请注意我使用Code First,因此我无法使用edmx映射器等。

3 个答案:

答案 0 :(得分:1)

这似乎是一个插入函数,Entity Framework 6.1本身支持它。有关其工作原理的信息位于Codeplex Documentation

基本上,您使用流畅的API将实体映射到存储过程,而不是默认的插入/更新/删除查询。举个例子:

modelBuilder
    .Entity<Test>()
    .MapToStoredProcedures (s =>
        s.Insert(i => i.HasName("sp_add_test")
            .Parameter(t => t.CreatedBy, "CreatedBy")
            .Parameter(t => t.CreatedDate, "CreatedDate")
            .Parameter(t => t.TestId, "TestId")
            .Parameter(t => t.TestStatusId, "TestStatusId")));

作为注释:

<强>限制

  • 存储过程映射目前只能使用Fluent API完成。将来我们可能会看一个基于属性(数据注释)的替代方案。
  • 您不能对给定实体(或实体层次结构)使用混合的存储过程和直接表访问。插入,更新和删除操作必须全部使用直接表访问或存储过程。

答案 1 :(得分:1)

官方称它不受支持。您可以使用由其中一个EF团队成员编写的附加组件,如帖子中所链接的那样,但这是关于它的。

你也可以使用工具来完成这项工作(比如LLBLGen Pro,它可以为你创建DbContext类中的proc调用映射:http://www.llblgen.com/documentation/4.2/Entity%20Framework/hh_goto.htm#V56/CodeFirstSupport.htm),但是你不允许这样做,因为你只是在寻找官方工具。我要说的是:关于EF的官方工具在很多方面很糟糕,所以如果你只是为这个和其他与EF相关的东西寻找官方工具,你就是为了地狱( (文字)乘车;)

答案 2 :(得分:0)

这些是扩展,但可以很容易地迁移到从DBContext类继承的主类之外的方法。

以下是我的所有SProcs / Function方法包含的3个常规签名。

    public static IEnumerable<T> ExecuteSProc<T> ( this DbContext ctx , string schema , string sproc , params SqlParameter[] para ) {
        return ctx.Database.SqlQuery<T>( "Execute " + schema + "." + sproc , para ).ToArray();
    }
    public static T ExecuteSProcSingle<T> ( this DbContext ctx , string schema , string sproc , params SqlParameter[] para ) {
        return ctx.Database.SqlQuery<T>( "Execute " + schema + "." + sproc , para ).SingleOrDefault();
    }

    public static int ExecuteSProc ( this DbContext ctx , string schema , string sproc , params SqlParameter[] para ) {
        return ctx.Database.ExecuteSqlCommand( "Execute " + schema + "." + sproc , para );
    }

我会定期发布我在几个帖子中达到高潮的小怪癖,在这里建立一个独特的实施概念:http://theithobbit.blogspot.com/

总的来说,你问:

public static class DbContextExtension {
    public static IEnumerable<T> ExecuteSProc<T> ( this DbContext ctx , string schema , string sproc , params SqlParameter[] para ) {
        return ctx.Database.SqlQuery<T>( "Execute " + schema + "." + sproc , para ).ToArray();
    }
    public static T ExecuteSProcSingle<T> ( this DbContext ctx , string schema , string sproc , params SqlParameter[] para ) {
        return ctx.Database.SqlQuery<T>( "Execute " + schema + "." + sproc , para ).SingleOrDefault();
    }

    public static int ExecuteSProc ( this DbContext ctx , string schema , string sproc , params SqlParameter[] para ) {
        return ctx.Database.ExecuteSqlCommand( "Execute " + schema + "." + sproc , para );
    }
}