在 EF Core 中执行存储过程,从 JOIN 返回 int。 Blazor(客户端)

Execute stored procedure in EF Core returning int from JOIN. blazor(client-side)

如何获取从 SQL 服务器中的存储过程返回的 EF Core 中的 int 值?

--Two tables, Employee and AspNetUsers--
CREATE PROCEDURE SP_GetIdEmployeeByUserName
     (@username varchar(100), @idemployee int output)
AS
BEGIN
    SELECT @idemployee = (SELECT e.Id 
                          FROM Employee e
                          JOIN AspNetUsers a ON e.IdUser = a.Id
                          WHERE a.Email = @username)

END

--Executing in database--
DECLARE @idemp INT;
EXEC SP_GetIdEmployeeByUserName 'someinsertedemail@gmail.com', @idemp output
SELECT @idemp;

在 SQL 服务器测试中返回正确的 Employee.Id

idemp `Id = 40`

现在在 Blazor(客户端)控制器中,我正在尝试执行存储过程。

[HttpGet]
[Route("getbyname")]
public int GetByName([FromQuery] string username)
{
        try
        {
            if (!string.IsNullOrEmpty(username))
            {
                SqlParameter paramUsername = new SqlParameter("@username", username);

                var paramOut = new SqlParameter
                {
                    ParameterName = "@idemp",
                    SqlDbType = System.Data.SqlDbType.Int,
                    Direction = System.Data.ParameterDirection.Output,
                };

                var result = _context
                    .Employee.FromSqlRaw
                    ($"EXEC SP_GetIdFuncByUserName @username, @idemp OUTPUT", paramUsername, paramOut)
                    .FirstOrDefault();

                Console.WriteLine("result = >>>>>>>>> " + result);

                return result.Id;
            }
            else
            {
                return 0;
            }

        }
        catch (Exception ex)
        {
            Console.WriteLine("ex -> " + ex);
            throw;
        }
    }

我得到这个异常:

FromSqlRaw or FromSqlInterpolated was called with non-composable SQL and with a query composing over it.
Consider calling AsEnumerable after the FromSqlRaw or FromSqlInterpolated method to perform the composition on the client side.

如果尝试

var result = _context
                .Database.ExecuteSqlRaw
                ($"EXEC SP_GetIdFuncByUserName @username, @idemp OUTPUT", paramUsername, paramOut);

它总是 returns -1 因为 none 行受到影响。

我看到了很多东西,但没有成功...在此先感谢

_context.Database.ExecuteSqlCommand if obsolete

您有不可组合的 SQL。关键是 Entity Framework 会写成

SELECT [Generated Column Names] FROM 
(
    @YOURQUERY
)

它这样做是为了确定一种格式,以便能够实现(嵌套的)结果、对它们进行分页等等。

如果您不select存储过程中的任何内容,则无法编写此查询。无论如何它都不是 return 结果集,因此您也无法从 dbContext.Employee select。那将是两个不同的查询。一个获取您已经拥有的ID:

var result = _context
            .Database.ExecuteSqlRaw
            ($"EXEC SP_GetIdFuncByUserName @username, @count OUTPUT", paramUsername, paramOut);

这确实是 return -1,因为您的查询有误。您提供了一个名为 @count 的参数,但提供了一个名为 @idemp.

的已配置参数

所以一定要正确传递参数:

var result = _context
                .Database.ExecuteSqlRaw
                ($"EXEC SP_GetIdFuncByUserName @username, @idemp OUTPUT", paramUsername, paramOut);

然后使用ID参数查询:

var employeeId = paramOut.Value;
var employee = _context.Employee.FirstOrDefault(e => e.Id == employeeId);