Reader没有读取DB值
本文关键字:DB 读取 Reader | 更新日期: 2023-09-27 18:17:39
我有一个问题一直困扰着我。问题是_reader没有读取任何内容。
我有这样的代码:
public DataEntities.Usuario GetUser(string field, string value)
{
using (SqlConnection connection = new SqlConnection(@"connectionstring"))
{
using (SqlCommand query = new SqlCommand())
{
DataEntities.Usuario _usuario = new DataEntities.Usuario();
if (field == "id" || field == "username" || field == "emailaddress")
{
query.Connection = connection;
query.CommandType = CommandType.StoredProcedure;
query.CommandText = "GetUser";
var pField = query.Parameters.AddWithValue("@Field", field);
pField.Direction = ParameterDirection.Input;
var pValue = query.Parameters.AddWithValue("@Value", value);
pValue.Direction = ParameterDirection.Input;
try
{
connection.Open();
SqlDataReader _reader = query.ExecuteReader();
>>> while(_reader.Read())
{
_usuario.EmailAddress = (string)_reader["EmailAddress"];
_usuario.Username = (string)_reader["Username"];
_usuario.FirstName = (_reader["FirstName"] != DBNull.Value) ? (string)_reader["FirstName"] : string.Empty;
_usuario.LastName = (_reader["LastName"] != DBNull.Value) ? (string)_reader["LastName"] : string.Empty;
_usuario.MobileNumber = (_reader["MobileNumber"] != DBNull.Value) ? (string)_reader["MobileNumber"] : string.Empty;
}
_reader.Close();
return _usuario;
}
catch (SqlException ex)
{
Console.WriteLine("SQL Error: " + ex.Message);
}
finally
{
connection.Close();
}
}
return _usuario;
}
}
}
我有这个存储过程:
CREATE PROCEDURE [dbo].[GetUser]
@Field nvarchar(100),
@Value nvarchar(100)
AS
SELECT EmailAddress,
Username,
FirstName,
LastName,
MobileNumber,
Register_Date
FROM Users
WHERE @Field = @Value
RETURN 0
这个没有返回任何东西。这不会产生异常,但当它到达while循环时,它跳转并结束,返回创建的对象,所有内容为空。
什么线索吗?我试图改变存储过程,但没有运气,
在T-SQL中不能参数化字段。您的查询实际上将作为WHERE 'someStringValue' = 'anotherStringValue'
执行,它永远不会为真,因此永远不会返回任何字段(当然,除非您输入@field = 'foo'
和@value = 'foo'
-在这种情况下,将返回每一行)。
如果你想让字段名是一个变量,你必须使用动态SQL
它没有读取任何内容,因为SQL没有返回任何内容。@Field = @Value并不像你想象的那样。如果您分别传递'a'和'b',您的查询将返回该条件为真的所有行(即0行)。
@Field只是一个变量,它不是一个列用户(我猜)你认为它可能。
变量名和字段名之间存在混淆。
你不能这样做。你必须使用动态SQL。
请注意潜在的SQL注入攻击!
我建议您首先在存储过程中验证您的输入。
CREATE PROCEDURE [dbo].[GetUser]
@Field nvarchar(100),
@Value nvarchar(100)
AS
-- Do check @Field to prevent SQL injection !
-- IF @Field <> 'Username' or @Field <> 'id' ...
-- RAISEERROR ...
DECLARE @sql NVARCHAR(max)
SET @sql =
'SELECT EmailAddress,
Username,
FirstName,
LastName,
MobileNumber,
Register_Date
FROM Users
WHERE [' + @Field + '] = ' + @Value
EXEC sp_executesql @sql
RETURN 0
EDIT:我刚刚意识到动态SQL的事情已经在我输入这个时被接受的答案中提到了。为了避免这个答案是多余的,这里有一个很好的技巧来处理DBNull.Value
而不重复_reader["]的事情。
_usuario.FirstName = (_reader["FirstName"] != DBNull.Value) ? (string)_reader["FirstName"] : string.Empty;
可以用
代替_usuario.FirstName = _reader["FirstName"] as string ?? string.Empty;
如果字段是DBNull对象,那么将其转换为字符串将导致null值。如果发生这种情况,一元??