我正在开发一个视频游戏比赛管理网站。
试图获取具有指定参数的用户(他们最后登录的本地电子咖啡馆城市和他们玩的游戏)。
为了获得最佳性能,我首先编写了一个存储过程并且它正在工作。
但是在从代码中调用时,会抛出以下异常。
异常消息:Column、parameter 或 variable @cityIds。: 无法找到数据类型 dbo.CityIds。
SQL
异常消息:Column、parameter 或 variable @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;
}
dbo.CityIdsTTV
,我觉得我们可能遗漏了某些东西。另外,应该使用EXECUTE dbo.spGetUsersByCityAndGame @gameProcessName, @cityIds READONLY
。 - Thom A