【发布时间】:2020-08-11 12:28:50
【问题描述】:
我正在开发一个视频游戏锦标赛处理网站。 尝试获取具有指定参数的用户(他们上次登录本地网吧的城市,以及他们玩的游戏)。 为了获得最佳性能,我从编写存储过程及其工作开始。 但是在抛出异常后从代码调用时。
Exception.Message:列、参数或变量@cityIds。 : 找不到数据类型 dbo.CityIds。
SQL
CREATE TYPE [dbo].[CityIds] AS TABLE(
[Id] [uniqueidentifier] NOT NULL
)
GO
ALTER PROCEDURE [dbo].[spGetUsersByCityAndGame]
@gameProcessName NVARCHAR(50),
@cityIds [CityIds] READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT users.Id
FROM AspNetUsers users WITH( NOLOCK )
JOIN
( -- select below finds last log entry by startDateTime column for each user
SELECT authLog1.*
FROM AuthenticationLog authLog1 WITH( NOLOCK )
LEFT OUTER JOIN
AuthenticationLog authLog2 WITH( NOLOCK )
ON authLog1.ClientId=authLog2.ClientId
AND authLog1.StartDateTime<authLog2.StartDateTime
WHERE authLog2.ClientId IS NULL
) lastAuthLog
ON users.Id=lastAuthLog.ClientId
JOIN
Club club
ON lastAuthLog.ClubId=club.Id
JOIN
City city
ON club.CityId=city.Id
JOIN
ProcessLogs processLog
ON lastAuthLog.Id=processLog.AuthenticationLogId
INNER JOIN @cityIds cids on city.Id = cids.Id
WHERE users.Birthday IS NOT NULL
AND users.PhoneNumber IS NOT NULL
AND users.UserName IS NOT NULL
AND users.Email IS NOT NULL
AND users.FullName IS NOT NULL
AND processLog.ProcessName=@gameProcessName;
END;
C#
private async Task<List<ApplicationUser>> GetUserByParameters(Guid gameId, IEnumerable<Guid> citiesIds)
{
Game game = await _gamesRepository.GetAsync(gameId);
SqlParameter gameNameParam = new SqlParameter("@gameProcessName", SqlDbType.NVarChar, 50)
{
Value = (object)game.ExecutableName ?? DBNull.Value
};
List<SqlDataRecord> table = new List<SqlDataRecord>();
foreach (Guid cityId in citiesIds)
{
SqlDataRecord tableRow = new SqlDataRecord(new SqlMetaData[] { new SqlMetaData("Id", SqlDbType.UniqueIdentifier) });
tableRow.SetGuid(0, cityId);
table.Add(tableRow);
}
SqlParameter citiesIdsParam = new SqlParameter
{
TypeName = "[dbo].[CityIds]",
SqlDbType = SqlDbType.Structured,
ParameterName = "@cityIds",
Value = table,
};
string sql = @"EXECUTE dbo.spGetUsersByCityAndGame @gameProcessName, @cityIds";
List<ApplicationUser> users = await _dbContext.Users.FromSqlRaw(sql, gameNameParam, citiesIdsParam).ToListAsync();
return users;
}
【问题讨论】:
-
在alter SPROC中你可以给
[dbo].[CityIds]而不是[CityIds]并尝试 -
考虑到
dbo.CityIdsTTV从未出现在您的代码中,我觉得我们在这里遗漏了一些东西。另外,应该是EXECUTE dbo.spGetUsersByCityAndGame @gameProcessName, @cityIds READONLY -
您可以尝试删除您的类型并使用正确的名称重新创建并在您的 SP 中使用它吗?
-
用户有权限吗?要使用表类型,需要对该类型具有
CONTROL权限。 (技术上EXECUTE和REFERENCES就足够了,但这并没有太多限制。) -
通常您使用将数据库行链接到 c# 数据表的 DataAdapter 查询数据库并将结果放入数据表中。然后你所要做的就是使用数据表的更新方法,然后将更改存储回数据库。
标签: c# sql .net sql-server