You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# GUID与SQL Server Uniqueidentifier转换及Google Chart数据查询问题

解决Google Chart中使用UniqueIdentifier参数查询SQL Server数据的问题

首先要明确一个关键误区:UniqueIdentifier(GUID)不能直接转换为int。GUID是128位的全局唯一标识符,而int只是32位整数,两者的取值范围、存储结构完全不同,强行转换要么会抛出溢出异常,要么会丢失大量信息,完全无法正确匹配数据库中的UserID。正确的做法是直接在存储过程和C#代码中使用uniqueidentifier类型来传递参数,下面是具体的实现步骤:

1. 调整存储过程,启用UserID参数

修改你的存储过程,打开注释的@UserID参数,并调整WHERE子句来支持按UserID过滤(如果需要同时保留ActivityID过滤,可以做成可选参数的形式,让查询更灵活):

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[rpGetUserActivities]
(
    @UserID uniqueidentifier, -- 启用UniqueIdentifier类型的参数
    @ActivityID INT = NULL -- 设置为可选参数,按需使用
)
AS
BEGIN
    SELECT [UserID], [ActivityID], [Title], [DateCreated]
    FROM [DB].[dbo].[DB_Activity]
    WHERE [DateCreated] IS NOT NULL 
    -- 支持单参数或多参数组合过滤
    AND (@ActivityID IS NULL OR [ActivityID] = @ActivityID)
    AND (@UserID IS NULL OR [UserID] = @UserID)
END

2. 修改C#中的数据访问方法,适配UniqueIdentifier参数

更新你的rpGetUserActivities方法,将参数类型改为Guid?(对应SQL的uniqueidentifier),并正确添加存储过程参数:

/// <summary>
/// 根据UserID(可选结合ActivityID)获取用户活动记录
/// </summary>
/// <param name="UserID">用户唯一标识符</param>
/// <param name="ActivityID">活动ID(可选)</param>
/// <returns>用户活动记录列表</returns>
public List<rpusersRecord> rpGetUserActivities(Guid? UserID, Int16? ActivityID = null)
{
    List<rpusersRecord> objrpusersRecords = null;
    objDB = new SqlDatabase(ConnectionString);
    using (DbCommand objcmd = objDB.GetStoredProcCommand("rpGetUserActivities"))
    {
        // 处理UserID参数:如果有值则传入,否则传DBNull
        if(UserID.HasValue)
        {
            objDB.AddInParameter(objcmd, "@UserID", SqlDbType.UniqueIdentifier, UserID.Value);
        }
        else
        {
            objDB.AddInParameter(objcmd, "@UserID", SqlDbType.UniqueIdentifier, DBNull.Value);
        }
        
        // 保留ActivityID参数的处理逻辑(如果需要)
        if(ActivityID.HasValue)
        {
            objDB.AddInParameter(objcmd, "@ActivityID", DbType.Int16, ActivityID.Value);
        }
        else
        {
            objDB.AddInParameter(objcmd, "@ActivityID", DbType.Int16, DBNull.Value);
        }
        
        try
        {
            using (DataTable dataTable = objDB.ExecuteDataSet(objcmd).Tables[0])
            {
                objrpusersRecords = ConvertTo<rpusersRecord>(dataTable);
            }
        }
        catch (Exception ex)
        {
            throw ex;
            return null;
        }
    }
    return objrpusersRecords;
}

3. 确保实体类的属性类型匹配

你的ConvertTo<T>方法依赖反射赋值,所以要保证rpusersRecord类中的UserID属性类型是Guid(或Guid?如果数据库中允许UserID为空):

public class rpusersRecord
{
    public Guid UserID { get; set; }
    public int ActivityID { get; set; }
    public string Title { get; set; }
    public DateTime DateCreated { get; set; }
    // 其他对应数据表的属性
}

为什么不能把UniqueIdentifier转成Int?

再强调一下这个错误思路的问题:

  • GUID的数值范围远超过int的上限(int最大是2147483647),强行转换会直接抛出OverflowException。
  • 即使通过截断等方式强行转换,也会丢失GUID的大部分唯一标识信息,导致无法正确匹配数据库中的用户ID,完全违背了GUID作为唯一标识符的设计初衷。

内容的提问来源于stack exchange,提问作者zufuzoje

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:49:27