简体   繁体   English

SqlParameterCollection仅接受非null SqlParameter类型的对象,不接受DBNull对象

[英]The SqlParameterCollection only accepts non-null SqlParameter type objects, not DBNull objects

Whenever I type nothing or null value in textboxes there is an error coming out. 每当我在文本框中不输入任何内容或返回null值时,就会出现错误。 My code is like this: 我的代码是这样的:

 SqlCommand cmd = con.CreateCommand();
 cmd.CommandText = "INSERT INTO Records 
                   ([Student ID], [First Name], [Last Name], [Middle Initial], 
                     Gender, Address, Status, Year, Email, Course, 
                    [Contact Number]) 
                    VALUES (@StudentID, @FirstName, @LastName , @MiddleInitial, 
                            @Gender, @Address, @Status, @Year, @Email, @Course, 
                            @ContactNumber)";

   SqlParameter p1 = new SqlParameter("@StudentID", SqlDbType.NChar);
   p1.Value = textBox1.Text;
   cmd.Parameters.Add(p1);
   SqlParameter p2 = new SqlParameter("@FirstName", SqlDbType.NVarChar);
   p2.Value = textBox2.Text;
   cmd.Parameters.Add(p2);
   SqlParameter p3 = new SqlParameter("@LastName", SqlDbType.NVarChar);
   p3.Value = textBox3.Text;
   cmd.Parameters.Add(p3);
   SqlParameter p4 = new SqlParameter("@MiddleInitial", SqlDbType.NChar);
   p4.Value = comboBox1.Text;
   cmd.Parameters.Add(p4);
   SqlParameter p5 = new SqlParameter("@Gender", SqlDbType.NChar);
   p5.Value = comboBox2.Text;
   cmd.Parameters.Add(p5);
   SqlParameter p6 = new SqlParameter("@Address", SqlDbType.VarChar);
   p6.Value = textBox4.Text;
   cmd.Parameters.Add(p6);
   SqlParameter p7 = new SqlParameter("@Status", SqlDbType.NChar);
   p7.Value = comboBox3.Text;
   cmd.Parameters.Add(p7);
   SqlParameter p8 = new SqlParameter("@Year", SqlDbType.VarChar);
   p8.Value = comboBox4.Text;
   cmd.Parameters.Add(p8);
   SqlParameter p9 = new SqlParameter("@Email", SqlDbType.VarChar);
   p9.Value = textBox5.Text;
   cmd.Parameters.Add(p9);
   SqlParameter p10 = new SqlParameter("@Course", SqlDbType.VarChar);
   p10.Value = comboBox5.Text;
   cmd.Parameters.Add(p10);
   SqlParameter p11 = new SqlParameter("@ContactNumber", SqlDbType.VarChar);
   p11.Value = textBox6.Text;
   cmd.Parameters.Add(p11);

   textBox1.Text = "";
   textBox2.Text = "";
   textBox3.Text = "";
   textBox4.Text = "";
   textBox5.Text = "";
   textBox6.Text = "";
   comboBox1.Text = "";
   comboBox2.Text = "";
   comboBox3.Text = "";
   comboBox4.Text = "";
   comboBox5.Text = "";
   if (cmd.Parameters.Contains(System.DBNull.Value))
   {
       MessageBox.Show("Please complete the fields", "Information...", 
                       MessageBoxButtons.OK, MessageBoxIcon.Warning, 
                       MessageBoxDefaultButton.Button1);
    }
    else
    {
       MessageBox.Show("Data Inserted!", "Information ... ", 
                       MessageBoxButtons.OK, MessageBoxIcon.Information, 
                       MessageBoxDefaultButton.Button1);
    }
    cmd.ExecuteNonQuery();
    con.Close();

The error is on: 错误发生在:

if(cmd.Parameters.Contains(System.DBNull.Value))

I'm using SQL Server and C#. 我正在使用SQL Server和C#。

SqlCommand cmd = con.CreateCommand();
cmd.CommandText = "INSERT INTO Records 
               ([Student ID], [First Name], [Last Name], [Middle Initial], 
                 Gender, Address, Status, Year, Email, Course, 
                [Contact Number]) 
                VALUES (@StudentID, @FirstName, @LastName , @MiddleInitial, 
                        @Gender, @Address, @Status, @Year, @Email, @Course, 
                        @ContactNumber)";
Control[] controls = {textBox1,textBox2, textBox3, textBox4, textBox5, textBox6, comboBox1, comboBox2, comboBox3, comboBox4, comboBox5};
foreach(Control c in controls){
  if(c.Text.Trim() == "") {
      MessageBox.Show("Please complete the fields", "Information...", 
                   MessageBoxButtons.OK, MessageBoxIcon.Warning, 
                   MessageBoxDefaultButton.Button1);
      c.Focus();//Focus it to let user enter some value again.
      return;

  }
}
//Initialize your parameters here
//....
//....
//....

try {
  cmd.ExecuteNonQuery();        
  MessageBox.Show("Data Inserted!", "Information ... ", 
                   MessageBoxButtons.OK, MessageBoxIcon.Information, 
                   MessageBoxDefaultButton.Button1);
  foreach(Control c in controls) c.Text = "";
}catch{}
finally {
  con.Close();
}

First of all, you need to look for whether the value property of any of the parameters is DBNull. 首先,您需要查看任何参数的value属性是否为DBNull。 You're trying check whether parameter object itself is DBNull, but you should be looking at the Value property. 您正在尝试检查参数对象本身是否为DBNull,但是您应该查看Value属性。 You can do that like this: 您可以这样做:

if ( cmd.Parameters.Any(p => DBNull.Value.Equals(p.Value)) )

Secondly, the .Text property of your textbox controls will never be null. 其次,文本框控件的.Text属性将永远不会为null。 At worst, it will be the empty string. 最糟糕的是,它将是空字符串。 So what you really want is code like this: 因此,您真正想要的是这样的代码:

if ( cmd.Parameters.Any(p => string.IsNullOrWhiteSpace((string)p.Value)) )

Finally, as an aside, even if the .Text property could be null , this is not the same as DBNull . 最后, .Text ,即使.Text属性可以为null ,这也与DBNull They are two different things. 他们是两个不同的东西。

Clean and effective approach. 清洁有效的方法。 Will help you in later developments. 将在以后的开发中为您提供帮助。 Change your code something like this: 更改您的代码,如下所示:

  1. Create a class called student and inside that class create properties for FirstName , LastName and others as required. 创建一个称为“学生”的类,并在该类中根据需要为FirstNameLastName和其他属性创建属性。 Something like this: 像这样:

     public class Student { public int StudentId {get;set;} public string FirstName {get;set;} public string FirstName {get;set;} public string MiddleInitial{get;set;} // upto ContactNumber or as required. } 
  2. Create a separate method for assigning parameters to SqlCommand . 创建用于将参数分配给SqlCommand的单独方法。 Here in these methods you can also put validations if you required using ternary operations ie ?,: 在这些方法中,如果需要使用三元运算(例如?),也可以在此处进行验证:

     private void CreateParameterList(ref Student s, ref SqlCommand cmd) { var parameters = new [] { new SqlParameter("@FirstName",s.FirstName), new SqlParameter("@LastName",s.LastName), : : new SqlParameter("@ContactNumber",s.ContactNumber) } cmd.Parameters.AddRange(parameters); } 
  3. Create a Method for Save and pass the above class as parameter. 创建一个保存方法,并将上述类作为参数传递。 You can also create a separate partial class in name of Student so as to access the members using same instance. 您也可以使用Student名称创建单独的局部类,以便使用相同的实例访问成员。 Call the method in step 2, so as to use the parameters. 在步骤2中调用方法,以使用参数。

     protected void MySaveFunction(Student s) { using(SqlConnection con= new SqlConnection(your_Connection_String)) { using(SqlCommmand cmd = new SqlCommand()) { cmd.CommandType = CommandType.Text/StoredProcedure; // it depends on what you are using cmd.Connection = con; cmd.CommandText=Your Query or Name of SP; con.Open(); CreateParameterList(ref s, ref cmd); try { int i = cmd.ExecuteNonQuery(); if(i>0) { //Show Success or return Success } } catch(SqlException sqlex) { //catch and log exception } finally { con.Close(); con.Dispose() } } } } 

Why don't you start over again and do some proper validation before getting to this point? 您为什么不重新开始并进行一些适当的验证,然后再进行此操作? You should never ever start creating objects and stuff if there is no need to do so. 如果没有必要,永远不要开始创建对象和东西。 So, make yourself a favor and add a validation method like in 因此,请帮自己一个忙,并添加一个验证方法,例如

private bool IsValid()
{
    return !Controls.OfType<TextBox>().Any(c=> String.IsNullOrEmpty(c.Text));
}

and then add a call just before the code to construct the sqlcommand and parameter collection 然后在代码之前添加一个调用以构造sqlcommand和参数集合

if(IsValid())
{
    // do you stuff here
}
else
{
   MessageBox.Show("Please complete the fields", "Information...", 
                   MessageBoxButtons.OK, MessageBoxIcon.Warning, 
                   MessageBoxDefaultButton.Button1);
}

Keep in mind this is not tested, I don't have VS right now and all is written manually, so maybe Control collection is not accessed that way. 请记住,这是未经测试的,我现在没有VS,并且所有代码都是手动编写的,因此可能无法以这种方式访问​​Control集合。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 SqlParameterCollection只接受非null的SqlParameter类型对象,而不接受DBNull对象 - SqlParameterCollection only accepts non-null SqlParameter type objects, not DBNull objects SqlParameterCollection 只接受非空的 SqlParameter 类型对象,而不接受 Microsoft.Data.SqlClient 中的 SqlParameter 对象 - The SqlParameterCollection only accepts non-null SqlParameter type objects, not SqlParameter objects in Microsoft.Data.SqlClient System.InvalidCastException:“SqlParameterCollection 只接受非空 SqlParameter 类型对象,不接受 SqlParameter 对象。” - System.InvalidCastException: 'The SqlParameterCollection only accepts non-null SqlParameter type objects, not SqlParameter objects.' sqlparametercollection 只接受非空的 sqlparameter 类型对象,而不是 byte[] 对象 - the sqlparametercollection only accepts non-null sqlparameter type objects not byte[] objects 错误:SqlParameterCollection仅接受非null的SqlParameter类型对象,而不接受String对象 - Error : The SqlParameterCollection only accepts non-null SqlParameter type objects, not String objects “SqlParameterCollection 只接受非空的 SqlParameter 类型对象,不接受 String 对象” - “SqlParameterCollection only accepts non-null SqlParameter type objects, not String objects” SqlParameterCollection仅接受非空的SqlParameter类型对象。 参数名称:值 - The SqlParameterCollection only accepts non-null SqlParameter type objects. Parameter name: value SqlParameterCollection 只接受非空的 Parameter 类型对象 - The SqlParameterCollection only accepts non-null Parameter type objects SqlParameterCollection仅接受非空的SqlParamter类型对象,而不接受String对象 - The SqlParameterCollection only accepts non-null SqlParamter type objects, not String objects Database.ExecuteSqlRaw - 只接受非空的 SqlParameter 类型对象 - Database.ExecuteSqlRaw - only accepts non-null SqlParameter type objects
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM