使用 SqlDataReader 读取 sql table 中的所有记录
Read all record in sql table using SqlDataReader
我想从“产品”table 中读取所有记录并从每条记录创建对象。
它只从数据库中获取一条记录,有什么想法可以帮助吗?
public IReadOnlyList<Product> Search(string name)
{
var result = new List<Product>();
using (var conn = new SqlConnection(connectionString))
{
if (name == null)
{
var command = new SqlCommand("SELECT * FROM Product ", conn);
conn.Open();
using var reader = command.ExecuteReader();
{
while (reader.Read())
{
var prod = new Product((int)reader["ID"], (string)reader["Name"],
(double)reader["Price"], (int)reader["Stock"], (int)reader["VATID"],
(string)reader["Description"]);
result.Add(prod);
reader.NextResult();
}
reader.Close();
conn.Close();
return result;
};
}
}
您的代码有错误:
删除行 reader.NextResult();
NextResult 用于移动到下一个结果集而不是下一个记录。
您使用 NextResult
将 reader 推进到下一个结果集。如果您有多个 sql 查询并且您将在 while 循环之后使用它,那么这很有意义。这里只是不必要和错误的。
您已经将 reader 推进到下一个 记录 Read
。
If I get rid of it, this error occur : Unable to cast object of type
'System.DBNull' to type 'System.String.
您可以使用 IsDBNull
:
int nameIndex = reader.GetOrdinal("Name");
string name = reader.IsDBNull(nameIndex) ? null : reader.GetString(nameIndex);
int descIndex = reader.GetOrdinal("Description");
string description = reader.IsDBNull(descIndex) ? null : reader.GetString(descIndex);
var prod = new Product((int)reader["ID"],
name,
(double)reader["Price"],
(int)reader["Stock"],
(int)reader["VATID"],
description);
将它用于每个可为空的列,对于数字列,您可以使用像 int?
.
这样的可为空的类型
绝对删除NextResult()
。这确实 NOT 在同一查询中的各个记录之间移动。 Read()
已经为您完成了。相反,NextResult()
允许您在同一个 CommandText
和 运行 中包含多个查询,一次访问数据库。
试试这个:
public IEnumerable<Product> Search(string name)
{
using (var conn = new SqlConnection(connectionString))
using (var command = new SqlCommand("SELECT * FROM Product ", conn))
{
if (!string.IsNullOrEmpty(name) )
{
command.CommandText += " WHERE Name LIKE @Name + '%'";
command.Parameters.Add("@Name", SqlDbType.NVarChar, 50).Value = name;
}
conn.Open();
using var reader = command.ExecuteReader();
{
while (reader.Read())
{
var prod = new Product((int)reader["ID"], reader["Name"].ToString(),
(double)reader["Price"], (int)reader["Stock"], (int)reader["VATID"],
reader["Description"].ToString());
yield return prod;
}
}
}
}
如果你有几个个结果集,你应该循环它们,也就是说你应该再放一个外层循环,例如
using var reader = command.ExecuteReader();
do {
while (reader.Read()) {
var prod = new Product(
Convert.ToInt32(reader["ID"]),
Convert.ToString(reader["Name"]),
Convert.ToDouble(reader["Price"]), // decimal will be better for money
Convert.ToInt32(reader["Stock"]),
Convert.ToInt32(reader["VATID"]),
Convert.ToString(reader["Description"])
);
result.Add(prod);
}
}
while (reader.NextResult());
注意外部 do .. while
循环,因为我们总是至少有一个结果集。
我想从“产品”table 中读取所有记录并从每条记录创建对象。 它只从数据库中获取一条记录,有什么想法可以帮助吗?
public IReadOnlyList<Product> Search(string name)
{
var result = new List<Product>();
using (var conn = new SqlConnection(connectionString))
{
if (name == null)
{
var command = new SqlCommand("SELECT * FROM Product ", conn);
conn.Open();
using var reader = command.ExecuteReader();
{
while (reader.Read())
{
var prod = new Product((int)reader["ID"], (string)reader["Name"],
(double)reader["Price"], (int)reader["Stock"], (int)reader["VATID"],
(string)reader["Description"]);
result.Add(prod);
reader.NextResult();
}
reader.Close();
conn.Close();
return result;
};
}
}
您的代码有错误:
删除行 reader.NextResult();
NextResult 用于移动到下一个结果集而不是下一个记录。
您使用 NextResult
将 reader 推进到下一个结果集。如果您有多个 sql 查询并且您将在 while 循环之后使用它,那么这很有意义。这里只是不必要和错误的。
您已经将 reader 推进到下一个 记录 Read
。
If I get rid of it, this error occur : Unable to cast object of type 'System.DBNull' to type 'System.String.
您可以使用 IsDBNull
:
int nameIndex = reader.GetOrdinal("Name");
string name = reader.IsDBNull(nameIndex) ? null : reader.GetString(nameIndex);
int descIndex = reader.GetOrdinal("Description");
string description = reader.IsDBNull(descIndex) ? null : reader.GetString(descIndex);
var prod = new Product((int)reader["ID"],
name,
(double)reader["Price"],
(int)reader["Stock"],
(int)reader["VATID"],
description);
将它用于每个可为空的列,对于数字列,您可以使用像 int?
.
绝对删除NextResult()
。这确实 NOT 在同一查询中的各个记录之间移动。 Read()
已经为您完成了。相反,NextResult()
允许您在同一个 CommandText
和 运行 中包含多个查询,一次访问数据库。
试试这个:
public IEnumerable<Product> Search(string name)
{
using (var conn = new SqlConnection(connectionString))
using (var command = new SqlCommand("SELECT * FROM Product ", conn))
{
if (!string.IsNullOrEmpty(name) )
{
command.CommandText += " WHERE Name LIKE @Name + '%'";
command.Parameters.Add("@Name", SqlDbType.NVarChar, 50).Value = name;
}
conn.Open();
using var reader = command.ExecuteReader();
{
while (reader.Read())
{
var prod = new Product((int)reader["ID"], reader["Name"].ToString(),
(double)reader["Price"], (int)reader["Stock"], (int)reader["VATID"],
reader["Description"].ToString());
yield return prod;
}
}
}
}
如果你有几个个结果集,你应该循环它们,也就是说你应该再放一个外层循环,例如
using var reader = command.ExecuteReader();
do {
while (reader.Read()) {
var prod = new Product(
Convert.ToInt32(reader["ID"]),
Convert.ToString(reader["Name"]),
Convert.ToDouble(reader["Price"]), // decimal will be better for money
Convert.ToInt32(reader["Stock"]),
Convert.ToInt32(reader["VATID"]),
Convert.ToString(reader["Description"])
);
result.Add(prod);
}
}
while (reader.NextResult());
注意外部 do .. while
循环,因为我们总是至少有一个结果集。