在我的AddProduct方法中,我的代码有问题。我收到一条消息,说我在测试代码时无法将DBNull转换为其他类型。有人提出这个问题的想法吗?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
namespace ProductMaintenance
{
class ProductDB
{
public static Product GetProduct(string code)
{
SqlConnection connection = MMABooksDB.GetConnection();
string select = "SELECT ProductCode, Description, UnitPrice "
+ "FROM Products "
+ "WHERE ProductCode = @ProductCode";
SqlCommand selectCommand = new SqlCommand(select, connection);
selectCommand.Parameters.AddWithValue("@ProductCode", code);
try
{
connection.Open();
SqlDataReader prodReader = selectCommand.ExecuteReader(CommandBehavior.SingleRow);
if (prodReader.Read())
{
Product product = new Product();
product.Code = prodReader["ProductCode"].ToString(); ;
product.Description = prodReader["Description"].ToString();
product.Price = ((decimal)prodReader["Price"]);
return product;
}
else
{
return null;
}
}
catch (SqlException ex)
{
throw ex;
}
finally
{
connection.Close();
}
}
public static bool UpdateProduct(Product oldProduct, Product newProduct)
{
SqlConnection connection = MMABooksDB.GetConnection();
string updateStatement = "UPDATE Products SET " + "Description = @NewDescription, " + "UnitPrice = @NewUnitPrice, " + "WHERE ProductCode = @oldProductCode " + "AND Description = @OldDescription " + "AND UnitPrice = @OldUnitPrice";
SqlCommand updateCommand =
new SqlCommand(updateStatement, connection);
updateCommand.Parameters.AddWithValue(
"@NewDescription", newProduct.Description);
updateCommand.Parameters.AddWithValue(
"@NewUnitPrice", newProduct.Price);
updateCommand.Parameters.AddWithValue(
"@OldProductCode", oldProduct.Code);
updateCommand.Parameters.AddWithValue(
"@OldDescription", oldProduct.Description);
updateCommand.Parameters.AddWithValue(
"@OldUnitPrice", oldProduct.Price);
try
{
connection.Open();
int count = updateCommand.ExecuteNonQuery();
if(count > 0)
return true;
else
return false;
}
catch(SqlException ex)
{
throw ex;
}
finally
{
connection.Close();
}
}
public static int AddProduct(Product product)
{
SqlConnection connection = MMABooksDB.GetConnection();
string insertStatement = "INSERT Products " + "(ProductCode, Description, UnitPrice) " + "VALUES (@ProductCode, @Description, @UnitPrice)";
SqlCommand insertCommand = new SqlCommand(insertStatement, connection);
insertCommand.Parameters.AddWithValue("@ProductCode", product.Code);
insertCommand.Parameters.AddWithValue("@Description", product.Description);
insertCommand.Parameters.AddWithValue("@UnitPrice", product.Price);
try
{
connection.Open();
insertCommand.ExecuteNonQuery();
string selectStatement = "SELECT IDENT_CURRENT('Products') FROM Products";
SqlCommand selectCommand = new SqlCommand(selectStatement, connection);
int productC = Convert.ToInt32(selectCommand.ExecuteScalar());
return productC;
}
catch (SqlException ex)
{
throw ex;
}
finally
{
connection.Close();
}
}
}
}
答案 0 :(得分:1)
您正在选择可能会返回null的IDENT_CURRENT
。
出错时或者如果调用者没有查看权限,则返回NULL 物体。
在SQL Server中,用户只能查看其元数据 用户拥有或已授予用户的安全性 允许。这意味着元数据发射,内置函数等 因为IDENT_CURRENT可能会返回NULL,如果用户没有任何 对象的许可。
根据您所描述的错误,这似乎是它失败的地方。 AddProduct
方法在执行INSERT
时不会尝试转换空值,因此当您尝试检索身份时,它可能是空值
int productC = Convert.ToInt32(selectCommand.ExecuteScalar());
由于对IDENT_CURRENT
的调用是该SQL命令中唯一的语句,因此除了SQL中的语法或其他错误外,所有这些都会将其缩小为权限。
那里有一些猜想和推论,但我怀疑它在哪里。
(如果从AddProduct
方法抛出错误,则无需发布其他所有内容。许多人 - 包括我自己 - 都会跳到结果,即错误是在您访问{时{1}}因为你没有在那里检查空值。但正如你所说的那样,这不是抛出异常的方法。当有这么多时,它很容易被遗漏不相关的代码。)