如何通过 FromSqlRaw 在 EF Core 3.0 中调用存储过程

Dan*_*Dan 21 c# entity-framework entity-framework-core .net-core-3.0

我最近从 EF Core 2.2 迁移到 EF Core 3.0。

不幸的是,我还没有找到调用返回实体的存储过程的方法。

在 EF Core 2.0 中是可能的:

var spParams = new object[] { "bla", "xx" };
var createdPath = ModelContext.Paths.FromSql("AddNodeWithPathProc  @p0, @p1", spParams).Single();
Run Code Online (Sandbox Code Playgroud)

在 EF Core 3.0 中,该方法FromSQL被替换为FromSqlRaw. 但是,我没有成功调用存储过程然后处理该值。这在存储过程将数据插入数据库时​​很有用。

所以在 EF Core 3.0 中,我使用以下代码:

var createdPath = ModelContext.Paths.FromSqlRaw("AddNodeWithPathProc @p0, @p1", spParams).Single();
Run Code Online (Sandbox Code Playgroud)

但它会抛出异常,因为生成的 SQL 是无效的,看起来像这样:

exec sp_executesql N'SELECT TOP(2) [p].[PathId], [p].[Level], [p].[NodeId], [p].[NodePath], [p].[NodePathString]
FROM (
     @sql @p0, @p1
) AS [p]',N'@p0 nvarchar(4000),@p1 nvarchar(4000), @sql nvarchar(100)',@p0=N'1a',@p1=N'', @sql=N'AddNodeWithPathProc'
Run Code Online (Sandbox Code Playgroud)

我尝试了很多变体,但没有成功。

我开始认为不可能使用ModelContext.[IQueryable].FromSqlRaw. 在我看来,这种失败的主要原因之一FromSqlRaw是,对于普通的 select 语句,LINQ 通常足够好。

有谁知道如何FromSqlRaw在 EF Core 3.0中结合使用存储过程?任何帮助是极大的赞赏。

提前致谢

PS:我知道您可以使用this.Database.ExecuteSqlRaw(SQL, parameters). 但是,这样就不可能检索存储过程查询的任何实体。

Dan*_*Dan 10

解决方案(感谢 David Browne,您应该将其发布为答案):

用 ToList 替换 Single 有效:-)

var createdPath = ModelContext.Paths.FromSqlRaw("AddNodeWithPathProc  {0}, {1}", nodeTitle, parentPathString).ToList();
Run Code Online (Sandbox Code Playgroud)


小智 6

这是非常奇怪的\xe2\x80\xa6 就在几天前我也遇到了同样的问题并关注了这篇文章。我接到这样的电话:

\n\n
 public IEnumerable<TableChange> GetTableLastChanges(string tableName, string keyColumn, out int synchronizationVersion)\n    {\n        var parameters = new[] {\n            new SqlParameter("@table_name", SqlDbType.VarChar) { Direction = ParameterDirection.Input, Value = tableName },\n            new SqlParameter("@key_column", SqlDbType.VarChar) { Direction = ParameterDirection.Input, Value = keyColumn },\n            new SqlParameter("@synchronization_version", SqlDbType.BigInt) { Direction = ParameterDirection.InputOutput, Value = 0 }\n        };\n\n        var changes = this.TableChanges.FromSqlRaw("[dbo].[GetTableLastChanges] @table_name, @key_column, @synchronization_version OUTPUT", parameters).ToList();\n\n        synchronizationVersion = Convert.ToInt32(parameters[2].Value);\n\n        return changes;\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在一切都很好,这个调用按预期工作。因此我应该承认 Core 3 上 EF 的数据集和参数返回没有问题。

\n


小智 1

我无法进行测试,但我认为以下方法会起作用:

var createdPath = ModelContext.Paths.FromSqlRaw("AddNodeWithPathProc {0}, {1}", parm1 parm2).Single();
Run Code Online (Sandbox Code Playgroud)

  • 不,这不起作用。刚刚测试过。无效的sql:-(。我相信它与生成的sql有关。如果我使用探查器检查sql,它总是遵循模式:sp_executesql 'SELECT * FROM {mySqlPassedInMethod}。我不会知道如何在此代码中传递存储过程。因此,.net 方法检测到传递的 sql 字符串用于存储过程并相应地调整生成的 sql,或者 T-SQL 中有一种我不知道的方法知道(我不是专家) (2认同)