1

在努力从 SQL 数据库中提取某些信息以在 C# 代码中使用以进行一些权限检查后,我决定回到基础并学习如何正确地完成它并慢慢地建立我的技能,以便我最终可以做我需要的事情去做。下面代码的目的是获取当前的 Active Directory 用户,然后进入一个包含用户名和其他信息的 SQL 表,找到一个匹配的,然后将其显示在 MessageBox 中。

string currentUser = System.Security.Principal.WindowsIdentity.GetCurrent().Name;

using (var cn = new SqlConnection(ConfigurationManager.ConnectionStrings["HSEProjRegConnectionString1"].ConnectionString))
using (var cmd = new SqlCommand())
{
    cn.Open();
    cmd.Connection = cn;
    cmd.CommandType = CommandType.Text;
    cmd.CommandText = "SELECT username FROM [tbl_Person] WHERE [username] LIKE '@currentUser'";

    SqlParameter param = new SqlParameter();
    cmd.Parameters.Add("@currentUser", SqlDbType.Char).Value = currentUser;

    MessageBox.Show("{0}", Convert.ToString((int)cmd.ExecuteScalar()));

    cn.Close();
}

不过有些不对劲。我收到以下错误和堆栈跟踪。第 38 行是 MessageBox 行。

System.NullReferenceException:对象引用未设置为对象的实例。

[NullReferenceException: Object reference not set to an instance of an object.]
HSE_project_Register.admin.Page_Load(Object sender, EventArgs e) in S:\IT\Development\Visual Studio Projects\HSE Project Register\admin\admin.aspx.cs:38
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +25
System.Web.UI.Control.LoadRecursive() +71
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3064

是什么导致该代码中的空引用异常?如果答案在堆栈跟踪中,有人可以向我解释一下吗?我发现堆栈跟踪非常混乱。

4

3 回答 3

2

您需要将查询更改为类似

SELECT username FROM [tbl_Person] WHERE [username] LIKE '%' + @currentUser + '%'

此外,您没有得到一个强制转换异常,而是一个空引用异常。

因此,您需要告诉我们页面 admin.aspx.cs 的第 38 行是什么?

为什么不将查询更改为类似

SELECT COUNT(username) as Cnt_UserName 
FROM [tbl_Person] 
WHERE [username] LIKE '%' + @currentUser + '%'

哪个应该总是返回一个 Int

我认为问题在于 type SqlDbType.Char。尝试将其更改为SqlDbType.VarChar.

看看下面的演示

SQL 小提琴演示

来自LIKE (Transact-SQL)

由于数据的存储方式,使用包含 char 和 varchar 数据的模式的字符串比较可能无法通过 LIKE 比较。

于 2013-06-11T04:34:55.993 回答
2

问题出在你的 sql 语句上

LIKE '@currentUser'"

这不会被识别为参数,您最好如下所示

cmd.CommandText = "SELECT username FROM [tbl_Person] WHERE [username] LIKE @currentUser";

当你设置参数

 cmd.Parameters.AddWithValue("@currentUser", '%' + currentUser + '%');
于 2013-06-11T04:41:12.573 回答
1

您收到此异常是因为返回的值来自:

(int)cmd.ExecuteScalar()

其实是null。然而,这里最让我感兴趣的是这个。您的查询说:

SELECT username FROM [tbl_Person]...

但是随后您正在获取结果并尝试将其转换为int. 我觉得不对。看来这Convert.ToString((int)cmd.ExecuteScalar())其实应该是这样cmd.ExecuteScalar() as string。这既可以处理null' ,也可以正确地转换其类型。

要修复您的查询,请考虑以下代码:

cmd.CommandText = "SELECT username FROM [tbl_Person] WHERE [username] LIKE @currentUser";

cmd.Parameters.AddWithValue("@currentUser", "%" + currentUser + "%";
于 2013-06-11T04:24:20.380 回答