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循环时,它跳转并结束,返回创建的对象,所有内容为空。

什么线索吗?我试图改变存储过程,但没有运气,

Reader没有读取DB值

在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值。如果发生这种情况,一元??