C# 我的id不为空,为什么我收到运行时错误?

C# 我的id不为空,为什么我收到运行时错误?,c#,sql,winforms,ado.net,runtime-error,C#,Sql,Winforms,Ado.net,Runtime Error,我得到这个运行时错误,并且我的id不是空的。我在我的代码中检查了它,您将看到,我正在使用telerikGridView 这是运行时错误 参数化查询“(@_fnamenvarchar(4),@_lnamenvarchar(2),@_phonenvarchar(6),@_a”需要未提供的参数“@_id” 我试图从另一个表单中获取id,这就是我这样写的原因 这是我的第一层代码 private void btnEdt_Click(object sender, EventArgs e) {

我得到这个运行时错误,并且我的
id
不是空的。我在我的代码中检查了它,您将看到,我正在使用telerik
GridView

这是运行时错误

参数化查询“(@_fnamenvarchar(4),@_lnamenvarchar(2),@_phonenvarchar(6),@_a”需要未提供的参数“@_id”

我试图从另一个表单中获取
id
,这就是我这样写的原因

这是我的第一层代码

private void btnEdt_Click(object sender, EventArgs e)
{
        Ref_View_Model = new View_model._View_Model();
        Ref_C = new Customers();

        foreach (var RowInfo in Ref_C.radGridView1.SelectedRows)
        {
            FireCell = RowInfo.Cells[0].Value.ToString();

            if (FireCell==null)
            {
                MessageBox.Show("null");
            }
        }

        //Ref_C.radGridView1.CurrentRow.Delete();
        Ref_C.customersTableAdapter.Update(Ref_C.sales_and_Inventory_SystemDataSet);
        Ref_C.customersTableAdapter.Fill(Ref_C.sales_and_Inventory_SystemDataSet.Customers);

        Ref_View_Model.GetEditCustomers(FireCell, txtFName.Text, txtLName.Text, txtPhn.Text, txtDdrss.Text);
} 
这是我在最后一层的代码

public void EditCustomres( string _id,string _fName, string _lName,string _phone, string _address)
{

        Connection_String = @"Data Source=MOSTAFA-PC;Initial Catalog=" + "Sales and Inventory System" + ";Integrated Security=TrueData Source=MOSTAFA-PC;Initial Catalog=" + "Sales and Inventory System" + ";Integrated Security=True;";
        Query = "update Customers " +
                                "set FName=@_fName  ,LName=@_lName  ,Phone=@_phone ,[Address]=@_address" +" "+
                                  "where Id like @_id";
        using (Con=new SqlConnection(Connection_String))
        using (Cmd=new SqlCommand(Query,Con))
        {
            Cmd.Parameters.Add("@_fName", SqlDbType.NVarChar);
            Cmd.Parameters.Add("@_lName", SqlDbType.NVarChar);
            Cmd.Parameters.Add("@_phone", SqlDbType.NVarChar);
            Cmd.Parameters.Add("@_address", SqlDbType.NVarChar);
            Cmd.Parameters.Add("@_id", SqlDbType.Int);

            Con = Cmd.Connection;
            Con.Open();

            Cmd.Parameters["@_fName"].Value = _fName;
            Cmd.Parameters["@_lName"].Value = _lName;
            Cmd.Parameters["@_phone"].Value = _phone;
            Cmd.Parameters["@_address"].Value = _address;
            Cmd.Parameters["@_id"].Value = _id;

            Cmd.ExecuteNonQuery();
            Cmd.Dispose();
            }
} 

您的
id
LIKE
子句不正确。它应该是这样的:

Id LIKE '%' + @_id + '%'
或:

或:

虽然最好使用简单的
=
而不是像这样的

where Id = @_id

在这种情况下,你真的不想使用LIKE,除非你有非常特殊的需求,需要它来更新看起来像你正在传递的ID的东西,但不是很像它

您正在以
SqlDbType.Int
的形式传入
@\u id
,但该变量实际上是
string
类型,这将导致在引擎盖下发生转换。如果传入的是空字符串,则该值将转换为
null
,这将导致您在帖子中提到的错误。请检查代码that导致调用
EditCustomres
,以确保它实际传入了正确的值。添加参数检查,如我添加的检查,将帮助您在调用堆栈中更早地跟踪此类问题

第一步是删除您的
LIKE
语句,因此请更新查询以使用:

where id = @_id
然后更新你的代码,因为你希望
\u id
变量是int,你不能只给它分配一个字符串,这可能就是为什么它被重置为
null
。要么更新方法以接受
int
参数而不是
string id
,要么在添加e参数:

int idValue = -1;
if (!int.TryParse(_id, NumberStyles.Integer, CultureInfo.InvariantCulture, out idValue))
{
    throw new ArgumentException("id", "Id must be a string which contains an integer value, the value of 'id' was: '" + _id + "'"); 
}

Cmd.Parameters.Add("@_id", SqlDbType.Int).Value = idValue;
您可能需要向文件中添加using语句:

using System.Globalization;
这是定义
numberstyle
CultureInfo
的地方。通常,Visual Studio会建议在哪里可以找到这些项目crtl+。会弹出一个屏幕,自动添加此语句


最终结果将是:

using System.Globalization;

....
....

public void EditCustomers( string _id,string _fName, string _lName,string _phone, string _address)
{
    int idValue = -1;
    if (!int.TryParse(_id, NumberStyles.Integer, CultureInfo.InvariantCulture, out idValue))
    {
       string message = "Id must be a string which contains an integer value, the value of 'id' was: '" + _id + "'";
       throw new ArgumentException("_id", message); 
    }

    Connection_String = @"Data Source=MOSTAFA-PC;Initial Catalog=" + "Sales and Inventory System" + ";Integrated Security=TrueData Source=MOSTAFA-PC;Initial Catalog=" + "Sales and Inventory System" + ";Integrated Security=True;";
    Query = @"update Customers 
                  set FName=@_fName, LName=@_lName, Phone=@_phone,[Address]=@_address
                  where Id = @_id";

    using (Con=new SqlConnection(Connection_String))
    using (Cmd=new SqlCommand(Query, con))
    {
        Cmd.Parameters.AddWithValue("@_fName", _fName);
        Cmd.Parameters.AddWithValue("@_lName", _lName);
        Cmd.Parameters.AddWithValue("@_phone", _phone);
        Cmd.Parameters.AddWithValue("@_address", _address);
        Cmd.Parameters.AddWithValue("@_id", idValue);

        Con.Open();
        Cmd.ExecuteNonQuery();
    }
}   
我还简化了代码。对SQL语句使用逐字字符串,删除对
Dispose
(使用
using(cmd)
和删除
Con=cmd.Connection
的调用,因为它实际上没有任何其他值

使用
.AddWithValue
方法也比单独创建和设置值容易


对于需要在SQL Server端连接字符串以形成SQL查询的解决方案,请务必小心,这可能会导致值注入不需要的SQL语句,从而将您的数据暴露给外部世界或允许外部人员破坏您的数据

还要小心使用
LIKE
语句来匹配更新值。除非在调用此语句的代码路径上有非常强的参数验证,否则请传入
id=“?”
id=“%”
或干脆
id=string。函数为空可能会更新所有记录,从而覆盖所有记录,使其具有相同的值。%1%将匹配1、10、21、31、11、100003…这极不可能是所需的行为


在delete和update语句中使用
=
而不是
类似的
,几乎总是理想的解决方案。如果
=
出现错误,则很可能是混合了数据类型(
string
,例如
int
).

谢谢,它奏效了,但您能告诉我第一种解决方案和第二种解决方案的区别吗?为什么是[%]是否需要?@MostafaBouzari…在第二种方法中,不需要指定
SqlDbType
。对于
之类的
,您应该使用
%
。您编写的异常会弹出,我的代码有什么问题?而且visual studio不知道这部分
NumberStyles.Integer,CultureInfo.InvariantCulture
在这种情况下,您可能会传入一个空字符串,而不是正在更新的客户id。或者它不是一个数字。请尝试设置断点并在运行时检查该值。NumberStyles和CultureInfo可能需要在文件顶部使用System.Globalization;
添加一个
。更新了答案。并更改了异常m显示传入的id的消息。
using System.Globalization;
using System.Globalization;

....
....

public void EditCustomers( string _id,string _fName, string _lName,string _phone, string _address)
{
    int idValue = -1;
    if (!int.TryParse(_id, NumberStyles.Integer, CultureInfo.InvariantCulture, out idValue))
    {
       string message = "Id must be a string which contains an integer value, the value of 'id' was: '" + _id + "'";
       throw new ArgumentException("_id", message); 
    }

    Connection_String = @"Data Source=MOSTAFA-PC;Initial Catalog=" + "Sales and Inventory System" + ";Integrated Security=TrueData Source=MOSTAFA-PC;Initial Catalog=" + "Sales and Inventory System" + ";Integrated Security=True;";
    Query = @"update Customers 
                  set FName=@_fName, LName=@_lName, Phone=@_phone,[Address]=@_address
                  where Id = @_id";

    using (Con=new SqlConnection(Connection_String))
    using (Cmd=new SqlCommand(Query, con))
    {
        Cmd.Parameters.AddWithValue("@_fName", _fName);
        Cmd.Parameters.AddWithValue("@_lName", _lName);
        Cmd.Parameters.AddWithValue("@_phone", _phone);
        Cmd.Parameters.AddWithValue("@_address", _address);
        Cmd.Parameters.AddWithValue("@_id", idValue);

        Con.Open();
        Cmd.ExecuteNonQuery();
    }
}