如何在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理这些连接。 我希望这是有帮助的。
我用ExecuteSqlCommand
和ExecuteSqlCommandAsync
有很多麻烦,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 });
我在这篇文章中写了更多关于它的内容 。