我正在尝试通过执行存储过程在数据库中进行批量更新。我正在调用DbContext.Database.ExecuteSqlCommand方法,如下所示:
_context.Database.ExecuteSqlCommand("EXECUTE TestProcedure");
在这个原始测试中,我的存储过程如下所示:
BEGIN
UPDATE TestTable
SET MyColumn = 'changed'
END
Select @@ROWCOUNT
当我直接在SSMS中执行SProc时,我得到返回的行数。但是,如果我通过上面发布的代码执行此操作,我总是得到-1的结果(即使SProc正确执行 - 我可以在我的表中验证)。
当我将代码更改为:
_context.Database.ExecuteSqlCommand("UPDATE TestTable SET MyColumn = "changed");
然后我获得正确数量的更新行。由于我的实际代码更详细,我想使用SProc,但我需要准确的行数。
我如何使用SProc?
答案 0 :(得分:2)
Database.ExecuteSqlCommand
返回受影响的行数,而不是SQL中任何SELECT...
语句的结果。
如果要返回结果集,则需要使用Database.SqlQuery
。
编辑:由于这是实体框架核心,SqlQuery
方法不存在(但是,它是计划好的)。但是,您可以执行类似这样的操作,即抓取原始连接并使用反射来返回数据。它不是特别有效但应该有效:
public static class DbContextExtensionss
{
public static IEnumerable<TEntity> ExecSQL<TEntity>(this DbContext context, string query) where TEntity : new()
{
using (var connection = context.Database.GetDbConnection())
using (var command = connection.CreateCommand())
{
command.CommandText = query;
command.CommandType = CommandType.Text;
if(connection.State != ConnectionState.Open)
{
connection.Open();
}
using (var result = command.ExecuteReader())
{
while (result.Read())
{
var entity = new TEntity();
foreach (PropertyInfo prop in typeof(TEntity).GetProperties())
{
if (!object.Equals(result[prop.Name], DBNull.Value))
{
prop.SetValue(entity, result[prop.Name], null);
}
}
yield return entity;
}
}
}
}
}
你会像这样使用它:
public class TestClass
{
public int RowCount { get; set; }
}
var results = _context.ExecSQL<>("EXECUTE TestProcedure");
foreach(var testClass in results)
{
Console.WriteLine(testClass.RowCount);
}
注意:您需要更改存储过程以命名它返回的列以匹配类:
SELECT @@ROWCOUNT AS [RowCount]