【发布时间】:2020-12-15 03:46:12
【问题描述】:
我在几年前编写了一个函数,并且在迁移到 .NET Core 3.1 之前一直运行良好。现在参数还没有传递给 SQL Server。我的功能是:
public async Task<IList<string>> GetTree(GetPayload payload)
{
var cx = this.uow.Repository<Organization>().Context;
var parameters = new List<SqlParameter>();
if (string.IsNullOrEmpty(payload.Code) == false)
parameters.Add(new SqlParameter("@code", payload.Code));
if (payload.ParentId.IsNullOrEmpty() == false)
parameters.Add(new SqlParameter("@parentId", payload.ParentId));
var orgRes = await cx.Organization.FromSqlRaw("SP_GetOrganization", parameters.ToArray()).ToListAsync();
return orgRes
}
调试这段代码时,参数成功地传到API。但是当用'FromSqlRaw' 调用SQL 时,参数显示为'0'。为什么?
这是我的存储过程:
DECLARE @RC int
DECLARE @code nvarchar(50)
DECLARE @parentId uniqueidentifier
DECLARE @perId uniqueidentifier
DECLARE @isDeleted bit
-- TODO: Set parameter values here.
EXECUTE @RC = [dbo].[SP_GetOrgTree]
@code
,@parentId
,@perId
,@isDeleted
GO
在 SQL 中,当像这样编辑代码时:程序运行没有问题。如何在 EF Core 中解决此问题?
DECLARE @RC int
DECLARE @code nvarchar(50)
DECLARE @parentId uniqueidentifier
DECLARE @perId uniqueidentifier
DECLARE @isDeleted bit
SET @code = 'sample code'
EXECUTE @RC = [dbo].[SP_GetOrgTree]
@code
,@parentId
,@perId
,@isDeleted
GO
【问题讨论】:
-
文档很清楚。也不需要使用
ToArray(),甚至不需要使用列表。parameters参数是一个params数组,这意味着您可以直接传递任意数量的参数值。无论问题是什么,都与传递多个参数无关 -
if (string.IsNullOrEmpty(payload.Code) == false) 等 - 有效载荷可以吗?顺便说一句,你不需要写“==false”,只要 (!string.IsNullOrEmpty(payload.Code))
-
我怀疑数据访问代码是不必要的复杂。对于初学者来说,不需要明确的工作单元或存储库。 DbContext is 一个工作单元,一个 DbSet is 一个存储库。试图取回隐藏在 UoW 中的上下文意味着代码已经泄漏。为什么要使用该存储过程,为什么要使用可变参数?您是否尝试使用包罗万象的查询?如果您只是根据需要使用带有不同
.Where()子句的 LINQ,则根本不需要这样做。一个包罗万象的查询也危害性能,而 LINQ 是一种避免这种情况的方法 -
@SeattlePigeon 不可能猜到哪里出了问题,除了说数据访问代码看起来......很麻烦。发布存储过程并检查实际内容。您是在要求人们猜测不可见的代码。我怀疑真正的解决方案是放弃不需要的自定义 UoW 和存储库,并正确使用 EF Core
-
@SeattlePigeon 在另一个已经提供的 UoW 和存储库之上使用 UoW 和“存储库”(实际上是数据访问对象)是一种丑陋的反模式,早在2009 年由 ORM 主要作者撰写。 Repository is the new Antipattern。 EF Core 不需要它们 -No need for repositories and Unit of Work with EF Core
标签: c# sql-server asp.net-core .net-core