C# 提供不一致返回值的存储过程

C# 提供不一致返回值的存储过程,c#,sql-server,stored-procedures,C#,Sql Server,Stored Procedures,我正在开发一个web表单,它验证用户以Excel文件的形式上传的数据。代码遍历电子表格中的每一行,并根据各种规则进行检查,其中之一是引用必须是唯一的值。我有一个存储过程,它将userID和referenceNum作为参数: BEGIN SET NOCOUNT ON; DECLARE @Status AS BIT IF EXISTS (SELECT [TransactionMstID] FROM [dbo].[tbl_Transactio

我正在开发一个web表单,它验证用户以Excel文件的形式上传的数据。代码遍历电子表格中的每一行,并根据各种规则进行检查,其中之一是引用必须是唯一的值。我有一个存储过程,它将
userID
referenceNum
作为参数:

BEGIN
    SET NOCOUNT ON;

    DECLARE @Status AS BIT

    IF EXISTS (SELECT [TransactionMstID] 
               FROM [dbo].[tbl_TransactionMst] 
               WHERE [TransactionRef] = @DocumentNumber 
                 AND [SupplierID] = @SupplierID)
    BEGIN 
        SET @Status = 0
    END
    ELSE
    BEGIN
        SET @Status = 1
    END

    SELECT @Status AS [Status]
END
当我在SQLServerManagementStudio(SSMS)中尝试不同的场景时,我会得到所需的输出,例如,引用存在时为“0”,引用不存在时为“1”

问题出现在我的C#代码中,它执行存储过程,但在我的测试中,无论数据是否存在,我都会得到相同的结果

这是C#的核心:

无论测试中
docnumber
的值是多少,它总是显示为
True
。我添加了一个断点,这样每次都可以进行检查,然后在SSMS中进行测试,结果会出现冲突

我的逻辑错了吗?Visual Studio是否以不同的方式对待这些值?至少在将其转换为
字符串时,结果如何不一致?在VS中似乎总是读取值“1”,但在SSM中则有所不同

编辑:以下是我的转换器方法的代码:

public static bool ConvertToBool(object value)
{
        bool result = false;

        if (value != null)
        {
            bool.TryParse(value.ToString(), out result);
        }

        return result;
}
没有做转换器(sic)代码认为它做的事情

bool.TryParse
如果value参数等于,则返回true,即文本字符串“true”。对于任何其他值,它都返回false,这意味着对于0和1,它都返回false

此外,T-SQL是数字。转换器代码其实不是必需的-只需将返回值转换为Int32并进行比较即可

using (var con = new SqlConnection(GlobalSettings.connection))
{
  con.Open();
  using (var cmd = new SqlCommand() { Connection = con, CommandType = CommandType.StoredProcedure, CommandText = "p_ValRefNumber" })
  {
    /* Assuming both parameters are integers.
       Change SqlDbType if necessary. */
    cmd.Parameters.Add(new SqlParameter() { ParameterName = "@DocumentNumber", SqlDbType = SqlDbType.Int, Value = Docnumber });
    cmd.Parameters.Add(new SqlParameter() { ParameterName = "@SupplierID", SqlDbType = SqlDbType.Int, Value = SupplierID });

    using (var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
    {
      return dr.Read() && (Convert.ToInt32(dr["Status"]) == 1)
    }
  }
}

在Docnumber上加一个断点。当语句的计算结果为True时,值是多少?目前它是“12324”-此用户在
[tbl\u TransactionMst]
中不存在的随机字符串。转换器的代码在哪里?也许这不是你想象的那样。我建议您在调试器中单步执行convertor.ConvertToBool.+1,检查它是否按预期转换为bool。出于兴趣,如果您一次只检查一个,为什么不使用输出参数并从中获取值?常见错误。几周前做的。将returnValue设置为false后,将继续执行while循环。所以,除非最后一行是假的,否则你总是在变为真。谢谢克里斯,你能给我解释一下那条回线吗?我不理解语法表达式的前半部分-
dr.Read()
-尝试从结果集中读取一行,如果成功,则返回true。第二部分将
Status
值转换为
Int32
,并将其与1进行比较。在普通语言中,表达式的内容是:“如果成功检索到一行,则返回,并且该行中的
Status
列等于1。”注意,如果前半部分返回false(即,如果未读取任何行),则运算符将不计算表达式的后半部分。哦,我明白了,这比我使用的要高效得多!您的代码工作正常,但它突出显示了从excel文件导入的另一个问题。我想你没有这方面的专业知识吧?我可能有。最好是发布一个新问题,而不是扩展讨论。不,这不是lambda。看。
using (var con = new SqlConnection(GlobalSettings.connection))
{
  con.Open();
  using (var cmd = new SqlCommand() { Connection = con, CommandType = CommandType.StoredProcedure, CommandText = "p_ValRefNumber" })
  {
    /* Assuming both parameters are integers.
       Change SqlDbType if necessary. */
    cmd.Parameters.Add(new SqlParameter() { ParameterName = "@DocumentNumber", SqlDbType = SqlDbType.Int, Value = Docnumber });
    cmd.Parameters.Add(new SqlParameter() { ParameterName = "@SupplierID", SqlDbType = SqlDbType.Int, Value = SupplierID });

    using (var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
    {
      return dr.Read() && (Convert.ToInt32(dr["Status"]) == 1)
    }
  }
}