如何在Entity Framework Core中运行存储过程?

我在一个asp.net核心应用程序中使用EF7(entity framework核心)。 你能指点我执行存储过程的正确方法吗? 用ObjectParameters((IObjectContextAdapter)this).ObjectContext.ExecuteFunction的旧方法不起作用。

现在已经解决了EF7中对存储过程的支持,这也支持多个结果集的映射。

检查这里的修复细节

你可以这样调用它 – var userType = dbContext.Set().FromSql("dbo.SomeSproc @Id = {0}, @Name = {1}", 45, "Ada");

EF7中尚未实现存储过程支持(7.0.0-beta3版本)。 您可以使用问题#245跟踪此function的进度。

现在,您可以使用ADO.NET以旧式的方式进行操作。

 var connection = (SqlConnection)context.Database.AsSqlServer().Connection.DbConnection; var command = connection.CreateCommand(); command.CommandType = CommandType.StoredProcedure; command.CommandText = "MySproc"; command.Parameters.AddWithValue("@MyParameter", 42); command.ExecuteNonQuery(); 

要执行存储过程,请使用执行RAW SQL查询的FromSql方法

例如

 var products= context.Products .FromSql("EXECUTE dbo.GetProducts") .ToList(); 

用于参数

 var productCategory= "Electronics"; var product = context.Products .FromSql("EXECUTE dbo.GetProductByCategory {0}", productCategory) .ToList(); 

要么

 var productCategory= new SqlParameter("productCategory", "Electronics"); var product = context.Product .FromSql("EXECUTE dbo.GetProductByName @productCategory", productCategory) .ToList(); 

执行RAW SQL查询或存储过程有一定的限制。您不能将其用于INSERT / UPDATE / DELETE。 如果要执行INSERT,UPDATE,DELETE查询,请使用ExecuteSqlCommand

 var categoryName = "Electronics"; dataContext.Database           .ExecuteSqlCommand("dbo.InsertCategory @p0", categoryName); 

"(SqlConnection)context" – 这种types转换不再起作用。 你可以这样做: "SqlConnection context;

".AsSqlServer()" – 不存在。

"command.ExecuteNonQuery();" – 不返回结果。 reader=command.ExecuteReader()可以工作。

使用dt.load(reader)…则必须将框架从5.0切换回4.51,因为5.0不支持数据表/数据集。 注意:这是VS2015 RC。

目前EF 7或EF Core不支持在devise器中导入存储过程的旧方法,并直接调用它们。 你可以看看路线图,看看未来会有哪些支持: EF核心路线图 。

因此,现在最好使用SqlConnection来调用存储过程或任何原始查询,因为您不需要整个EF来完成这项工作。 这里有两个例子:

调用返回单个值的存储过程。 在这种情况下string。

 CREATE PROCEDURE [dbo].[Test] @UserName nvarchar(50) AS BEGIN SELECT 'Name is: '+@UserName; END 

调用返回列表的存储过程。

 CREATE PROCEDURE [dbo].[TestList] AS BEGIN SELECT [UserName], [Id] FROM [dbo].[AspNetUsers] END 

要调用这些存储过程,最好创build包含所有这些函数的静态类,例如我称之为DataAccess类,如下所示:

 public static class DataAccess { private static string connectionString = ""; //Your connection string public static string Test(String userName) { using (SqlConnection conn = new SqlConnection(connectionString)) { conn.Open(); // 1. create a command object identifying the stored procedure SqlCommand cmd = new SqlCommand("dbo.Test", conn); // 2. set the command object so it knows to execute a stored procedure cmd.CommandType = CommandType.StoredProcedure; // 3. add parameter to command, which will be passed to the stored procedure cmd.Parameters.Add(new SqlParameter("@UserName", userName)); // execute the command using (var rdr = cmd.ExecuteReader()) { if (rdr.Read()) { return rdr[0].ToString(); } else { return null; } } } } public static IList<Users> TestList() { using (SqlConnection conn = new SqlConnection(connectionString)) { conn.Open(); // 1. create a command object identifying the stored procedure SqlCommand cmd = new SqlCommand("dbo.TestList", conn); // 2. set the command object so it knows to execute a stored procedure cmd.CommandType = CommandType.StoredProcedure; // execute the command using (var rdr = cmd.ExecuteReader()) { IList<Users> result = new List<Users>(); //3. Loop through rows while (rdr.Read()) { //Get each column result.Add(new Users() { UserName = (string)rdr.GetString(0), Id = rdr.GetString(1) }); } return result; } } } } 

和Users类是这样的:

 public class Users { public string UserName { set; get; } public string Id { set; get; } } 

顺便说一下,你不需要担心为sql的每个请求打开和closures连接的性能,因为asp.net正在为您pipe理这些连接。 我希望这是有帮助的。

我用ExecuteSqlCommandExecuteSqlCommandAsync有很多麻烦,IN参数很容易,但是OUT参数非常困难。

我不得不恢复使用DbCommand像这样 –

 DbCommand cmd = _context.Database.GetDbConnection().CreateCommand(); cmd.CommandText = "dbo.sp_DoSomething"; cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.Add(new SqlParameter("@firstName", SqlDbType.VarChar) { Value = "Steve" }); cmd.Parameters.Add(new SqlParameter("@lastName", SqlDbType.VarChar) { Value = "Smith" }); cmd.Parameters.Add(new SqlParameter("@id", SqlDbType.BigInt) { Direction = ParameterDirection.Output }); 

我在这篇文章中写了更多关于它的内容 。