C# 处理DataGridView值中要插入SQL Server的空数据

C# 处理DataGridView值中要插入SQL Server的空数据,c#,sql-server,datagridview,C#,Sql Server,Datagridview,我正在使用C#Winforms从DataGridView到我的sqlserver插入一些NULL或Empty值。但是这行有一个错误 cmd.Parameters.Add("@Status", SqlDbType.VarChar).Value = dataGridWork.Rows[i].Cells[1].Value.ToString(); System.NullReferenceException:“对象引用未设置为对象的实例。” 因为它期望的值不是NULL(如果我错了,请纠正我)。这是我的I

我正在使用
C#Winforms
DataGridView
到我的
sqlserver
插入一些
NULL
Empty
值。但是这行有一个错误

cmd.Parameters.Add("@Status", SqlDbType.VarChar).Value = dataGridWork.Rows[i].Cells[1].Value.ToString();
System.NullReferenceException:“对象引用未设置为对象的实例。”

因为它期望的值不是NULL(如果我错了,请纠正我)。这是我的
INSERT
查询的代码

using (SqlConnection conn = new SqlConnection(@"Server=" + ip + "," + port + "; Database=records; User ID=" + sqlid + "; Password=" + sqlpass + ""))
{
    conn.Open();
    for (int i = 0; i < dataGridWork.Rows.Count; i++)
    {
        using (SqlCommand cmd = new SqlCommand(@"INSERT INTO [dbo].[workorder]
                                            ([Work Order]
                                            ,[Plate No.]
                                            ,[Date]
                                            ,[Status]
                                            ,[Work Description]
                                            ,[Labor Price]
                                            ,[Item]
                                            ,[Unit Price]
                                            ,[Qty]
                                            ,[Unit]
                                            ,[Item Price]
                                            ,[Mechanic]
                                            ,[Deposit])
                                        VALUES
                                            (@WOrder
                                            ,@Plate
                                            ,@Date
                                            ,@Status
                                            ,@WDesc
                                            ,@LPrice
                                            ,@Item
                                            ,@UPrice
                                            ,@Qty
                                            ,@Unit
                                            ,@IPrice
                                            ,@Mechanic
                                            ,@Deposit)", conn))
        {
            cmd.Parameters.Add("@WOrder", SqlDbType.VarChar).Value = "WRK" + Properties.Settings.Default.work;
            cmd.Parameters.Add("@Plate", SqlDbType.VarChar).Value = plate;
            cmd.Parameters.Add("@Date", SqlDbType.Date).Value = dataGridWork.Rows[i].Cells[0].Value.ToString();
            cmd.Parameters.Add("@Status", SqlDbType.VarChar).Value = dataGridWork.Rows[i].Cells[1].Value.ToString();
            cmd.Parameters.Add("@WDesc", SqlDbType.VarChar).Value = dataGridWork.Rows[i].Cells[2].Value.ToString();
            cmd.Parameters.Add("@LPrice", SqlDbType.Decimal, 18).Value = Convert.ToDouble(dataGridWork.Rows[i].Cells[3].Value);
            cmd.Parameters.Add("@Item", SqlDbType.VarChar).Value = dataGridWork.Rows[i].Cells[4].Value.ToString();
            cmd.Parameters.Add("@UPrice", SqlDbType.Decimal, 18).Value = Convert.ToDouble(dataGridWork.Rows[i].Cells[5].Value);
            cmd.Parameters.Add("@Qty", SqlDbType.Int).Value = dataGridWork.Rows[i].Cells[6].Value.ToString();
            cmd.Parameters.Add("@Unit", SqlDbType.VarChar).Value = dataGridWork.Rows[i].Cells[7].Value.ToString();
            cmd.Parameters.Add("@IPrice", SqlDbType.Decimal, 18).Value = Convert.ToDouble(dataGridWork.Rows[i].Cells[8].Value);
            cmd.Parameters.Add("@Mechanic", SqlDbType.VarChar).Value = txtWMech.Text;
            cmd.Parameters.Add("@Deposit", SqlDbType.Decimal, 18).Value = numWDepo.Value;
            cmd.ExecuteNonQuery();
        }
    }
    conn.Close();
    Properties.Settings.Default.work = Properties.Settings.Default.work + 1;
}

现在,它可以为my
DataGridView
中的每一行插入值。但是有没有办法缩短或消除
If-Else
语句?或者为了使代码看起来更干净?

您可以为此使用扩展方法。e、 g

public static T GetValueOrDefault<T>(this DataGridViewRow sourceRow, int columnIndex, T defaultValue = default(T))
{
    var o = sourceRow.Cells[columnIndex];
    if (o is T) return (T)o; 
    return defaultValue;
}
public static T GetValueOrDefault(此DataGridViewRow sourceRow,int columnIndex,T defaultValue=default(T))
{
var o=sourceRow.Cells[列索引];
如果(o)为T,则返回(T)o;
返回默认值;
}
请按如下方式使用:

dataGridWork.Rows[i].GetValueOrDefault<int>(1,0);
dataGridWork.Rows[i].GetValuerDefault(1,0);

您可以使用-
cmd.Parameters.Add(“@Status”,SqlDbType.VarChar)。Value=dataGridWork.Rows[i]。Cells[1]。Value?.ToString()??DBNull.Value-值后的
表示“如果不为空,请使用此值”,而
表示“如果为空,请使用此值”使用Sql Server Management Studio(SSMS),并使用资源管理器检查数据库表列是否设置为允许为空。查找表和打开的列。列应该显示类型,然后显示null,比如:ID(varchar(20),null)@stuartd,但是如果是int、decimal或double呢<代码>Convert.ToDouble(dataGridWork.Rows[i].Cells[3].Value??DBNull.Value)我已尝试此操作,但它返回一个error@Jepher对不起,我错过了。如果该值为null,是否要将
0
null
发送到数据库?对于第一种情况,它将是
Convert.ToDouble(dataGridWork.Rows[i].Cells[3].Value)我没有使用
??数值的DBNull.Value
。只是一个普通的
参数。使用转换后的值添加
cmd.Parameters.Add(“@LPrice”,SqlDbType.Decimal,18).Value=Convert.ToDouble(dataGridWork.Rows[i].Cells[3].Value)并且它正在工作。它返回0表示
Int
,0.00表示
Decimal
。谢谢@stuartdDataGridRow!=DataGridViewRow作为示例引用,它指向
sourceRow
的一个错误,指出
无法将带[]的索引应用于“DataGridViewRow”类型的表达式
。我尝试将其更改为
此DataRow sourceRow
。它将错误指向
GetValueOrDefault
dataGridWork.Rows[i].GetValueOrDefault<int>(1,0);