简体   繁体   English

Entity Framework Code First是否支持存储过程?

[英]Does Entity Framework Code First support stored procedures?

I've watched several presentations of EF Code First and haven't seen how EFCF works with stored procedures. 我已经看了几次EF Code First的演示,还没有看到EFCF如何与存储过程一起工作。

How can I declare a method that will use some sp? 如何声明一个将使用某些sp的方法? Can I pass an entity to a method that calls sp without manually mapping entity properties to sp parameters? 我是否可以将实体传递给调用sp的方法,而无需手动将实体属性映射到sp参数?

Also, what happens if I change my model? 另外,如果我改变模型会发生什么? Would it drop my sp while recreating table from model? 它会在从模型中重新创建表格时丢失我的sp吗? And what about triggers? 触发器呢?

If these things are not supported, are there any plans to support them in future? 如果不支持这些东西,是否有计划在将来支持它们?

EDIT: My original answer for EF4.1 (below) is now out of date. 编辑:我对EF4.1(下面)的原始答案现已过时。 Please see the answer below from Diego Vega (who works on the EF team at Microsoft)! 请参阅以下来自Diego Vega (他在Microsoft的EF团队工作) 的答案


@gsharp and Shawn Mclean: Where are you getting this information? @gsharp和Shawn Mclean:你在哪里得到这些信息? Don't you still have access to the underlying ObjectContext? 你还没有访问底层的ObjectContext吗?

IEnumerable<Customer> customers = 
    ((IObjectContextAdapter)this)
    .ObjectContext.ExecuteStoreQuery<Customer>("select * from customers");

Replace the "select" statement with a stored proc, and there you go. 用存储的proc替换“select”语句,然后就可以了。

As for your other question: Yes, unfortunately your sp's will get clobbered. 至于你的另一个问题:是的,不幸的是你的sp会被破坏。 You may need to add the "CREATE PROCEDURE" statements in your code. 您可能需要在代码中添加“CREATE PROCEDURE”语句。

For EF 4.2: 对于EF 4.2:

var customers = context.Database.SqlQuery<Customer>("select * from customers")

Update: From EF6 on, EF Code First does support stored procedure mapping for inserts, updates and deletes. 更新:从EF6开始,EF Code First支持插入,更新和删除的存储过程映射。 You can specify stored procedure mapping during model creation using the MapToStoredProcedures method. 您可以使用MapToStoredProcedures方法在模型创建期间指定存储过程映射。 We also support automatic scaffolding of basic stored procedures for those operations. 我们还支持这些操作的基本存储过程的自动脚手架。 See the feature specification here . 请参阅此处的功能规范。

Original answer: We won't have support for mapping stored procedures in the model in Code-First in the first release, nor we will have a way to automatically generate stored procedures for CRUD operations from your types. 原始答案:我们不支持在第一版中的Code-First模型中映射存储过程,也没有办法从类型中自动生成CRUD操作的存储过程。 These are features that we would like to add in the future. 这些是我们希望将来添加的功能。

As it was mentioned in this thread, it is possible to fall back to ObjectContext but DbContext also provides nice APIs to execute native SQL queries and commands (eg DbSet.SqlQuery, DbContext.Database.SqlQuery and DbContext.Database.ExecuteSqlCommand). 正如在这个线程中提到的那样,可以回退到ObjectContext,但DbContext也提供了很好的API来执行本机SQL查询和命令(例如DbSet.SqlQuery,DbContext.Database.SqlQuery和DbContext.Database.ExecuteSqlCommand)。 The different SqlQuery versions have the same basic materialization functionality that exists in EF4 (like ExecuteStoreQuery: http://msdn.microsoft.com/en-us/library/dd487208.aspx ). 不同的SqlQuery版本具有与EF4中相同的基本实现功能(如ExecuteStoreQuery: http//msdn.microsoft.com/en-us/library/dd487208.aspx )。

Hope this helps. 希望这可以帮助。

    public IList<Product> GetProductsByCategoryId(int categoryId)
    {
        IList<Product> products;

        using (var context = new NorthwindData())
        {
            SqlParameter categoryParam = new SqlParameter("@categoryID", categoryId);
            products = context.Database.SqlQuery<Product>("Products_GetByCategoryID @categoryID", categoryParam).ToList();
        }

        return products;
    }

    public Product GetProductById(int productId)
    {
        Product product = null;

        using (var context = new NorthwindData())
        {
            SqlParameter idParameter = new SqlParameter("@productId", productId);
            product = context.Database.SqlQuery<Product>("Product_GetByID @productId", idParameter).FirstOrDefault();
        }

        return product;
    }

A more type safe solution would be this: 更安全的解决方案是:

http://strugglesofacoder.blogspot.be/2012/03/calling-stored-procedure-with-entity.html http://strugglesofacoder.blogspot.be/2012/03/calling-stored-procedure-with-entity.html

The usage of this class is: 这个类的用法是:

var testProcedureStoredProcedure = new TestProcedureStoredProcedure() { Iets = 5, NogIets = true };

var result = DbContext.Database.ExecuteStoredProcedure(testProcedureStoredProcedure);

For .NET Core (EntityFrameworkCore), I have been able to get them working. 对于.NET Core(EntityFrameworkCore),我已经能够让它们正常工作。

Might not be the neatest, but this definitely works. 可能不是最好的,但这绝对有效。

The migration for adding the stored procedure looks like this : 添加存储过程的迁移如下所示

using Microsoft.EntityFrameworkCore.Migrations;
using System.Text;

namespace EFGetStarted.AspNetCore.NewDb.Migrations
{
    public partial class StoredProcedureTest : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("CREATE PROCEDURE GetBlogForAuthorName");
            sb.AppendLine("@authorSearch varchar(100)");
            sb.AppendLine("AS");
            sb.AppendLine("BEGIN");
            sb.AppendLine("-- SET NOCOUNT ON added to prevent extra result sets from interfering with SELECT statements.");
            sb.AppendLine("SET NOCOUNT ON;");
            sb.AppendLine("SELECT  Distinct Blogs.BlogId, Blogs.Url");
            sb.AppendLine("FROM Blogs INNER JOIN");
            sb.AppendLine("Posts ON Blogs.BlogId = Posts.BlogId INNER JOIN");
            sb.AppendLine("PostsAuthors ON Posts.PostId = PostsAuthors.PostId Inner JOIN");
            sb.AppendLine("Authors on PostsAuthors.AuthorId = Authors.AuthorId");
            sb.AppendLine("Where Authors.[Name] like '%' + @authorSearch + '%'");
            sb.AppendLine("END");

            migrationBuilder.Sql(sb.ToString());
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.Sql("DROP PROCEDURE GetBlogForAuthorName");
        }
    }
}

I could then call it with the following code: 然后我可以使用以下代码调用它:

var blogs = _context.Blogs.FromSql("exec GetBlogForAuthorName @p0", "rod").Distinct();

Later tried getting some of the related data (one to many relationship data eg Post content) and the blog came back with the filled Post content as exptected. 后来尝试获取一些相关数据(一对多关系数据,例如帖子内容),并且博客回来时已填写的帖子内容被检测到。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 先在Entity Framework代码中自动生成存储过程 - Generate stored procedures automatically in Entity Framework code-first 首先在实体框架代码中更改CUD存储过程的命名约定 - Change naming convention of CUD stored procedures in entity framework code first 实体框架代码首先使用复合主键映射存储过程 - Entity framework code first map stored procedures with composite primary keys 具有多个结果集和自定义实体的实体框架代码优先存储过程 - Entity Framework Code First Stored Procedures with Multiple Result Sets and custom entity 实体框架和存储过程 - Entity Framework & Stored Procedures 实体框架4 +存储过程 - Entity Framework 4 + stored procedures 在 Asp.Net MVC 5 中使用实体框架 6 代码优先方法调用存储过程 - Call stored procedures with Entity Framework 6 code first approach in Asp.Net MVC 5 实体框架代码第一:如何使用比模型属性少的参数映射到存储过程? - Entity Framework Code First: How to map to stored procedures with less parameters than model properties? 是否可以使用代码优先实体框架在数据库上生成基本的CRUD存储过程? - Is it possible to generate basic CRUD stored procedures on database with code-first entity framework? 实体框架数据库首先不会为存储过程生成所有复杂类型 - Entity Framework database first does not generated all complex types for stored procedures
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM