Ошибка: объект должен реализовывать IConvertible

Я пытаюсь вставить элементы списка и значение текстового поля для каждого элемента списка в базу данных, когда я получаю сообщение об ошибке ниже.

Если я пытаюсь вставить элементы списка только в случае успеха, но когда я пытаюсь вставить значение текстового поля, я получаю эту ошибку. Подскажите, пожалуйста, что я делаю не так.

Сообщение об ошибке: Объект должен реализовывать IConvertible.
Описание: во время выполнения текущего веб-запроса произошло необработанное исключение. Пожалуйста, просмотрите трассировку стека для получения дополнительной информации об ошибке и о том, где она возникла в коде.

Сведения об исключении: System.InvalidCastException: объект должен реализовывать IConvertible.

Ошибка источника:

Строка 60: 
Строка 61:             
Строка 62:             cmd.ExecuteNonQuery();
Строка 63: 
Строка 64: 

код #

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Specialized;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Data.SqlClient;
using System.Web.UI.HtmlControls;

public partial class test1 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    private string GetConnectionString()
    {

        return System.Configuration.ConfigurationManager.ConnectionStrings["RM_Jan2011ConnectionString"].ConnectionString;

    }

    private void InsertRecords(StringCollection sc)
    {

        SqlConnection conn = new SqlConnection(GetConnectionString());

        StringBuilder sb = new StringBuilder(string.Empty);


        foreach (string item in sc)
        {
            const string sqlStatement = "INSERT INTO FileID(File_Code, Dept_Code) VALUES(@File_Code, @Dept_Code)";

            sb.AppendFormat("{0}('{1}'); ", sqlStatement, item);

        }

        try
        {
            conn.Open();

            SqlCommand cmd = new SqlCommand(sb.ToString(), conn);



           cmd.Parameters.Add("@File_Code", SqlDbType.VarChar);
        cmd.Parameters["@File_Code"].Value = ListBox2.Items;


        cmd.Parameters.Add("@Dept_Code", SqlDbType.VarChar);
        cmd.Parameters["@Dept_Code"].Value = DropDownList1.Text;



            cmd.ExecuteNonQuery();


            Page.ClientScript.RegisterClientScriptBlock(typeof(Page), "Script", "alert ('Records Successfuly Saved!');", true);
        }


        catch (System.Data.SqlClient.SqlException ex)
        {
            string msg = "Insert Error:";

            msg += ex.Message;

            throw new Exception(msg);
        }
        finally
        {
            conn.Close();
        }
    }


    protected void Button4_Click(object sender, EventArgs e)
    {

        int myint = Convert.ToInt32(TextBox1.Text) + 1;

        for (int i = 1; i < myint; i++)
        {
            ListBox2.Items.Add(DropDownList1.SelectedItem.ToString() + i.ToString());

        }
    }

    protected void Button1_Click(object sender, EventArgs e)
    {

        StringCollection sc = new StringCollection();

        foreach (ListItem item in ListBox2.Items)
        {
            {
                sc.Add(item.Text);
                sc.Add(DropDownList1.Text);
            }
        }
        InsertRecords(sc);
    }

Я хочу добавить все значения списка в базу данных.

Во-вторых, даже если я пытаюсь использовать.

SelectedItem

тогда я получаю следующую ошибку.

Ошибка вставки: неверный синтаксис рядом с 'CPD1'. 
Неверный синтаксис рядом с 'CPD'. 
Неверный синтаксис рядом с 'CPD2'. 
Неверный синтаксис рядом с 'CPD'. 
Неверный синтаксис рядом с 'CPD3'. 
Неверный синтаксис рядом с 'CPD'.

Любая идея, где я иду не так?

6 ответов

Если ваш список содержит только строковые элементы, вам нужно изменить следующую строку

cmd.Parameters["@File_Code"].Value = ListBox2.Items

в

cmd.Parameters["@File_Code"].Value = ListBox2.SelectedItem

если элементы сложные объекты, добавьте.ToString() в конце

UPD: если вы хотите добавить все элементы ListBox, вам нужно перебрать его коллекцию элементов и выполнить запрос вставки для каждого элемента, что-то вроде этого:

foreach(string item in ListBox2.Items)
{
    SqlCommand cmd = new SqlCommand(sqlStatement, conn);       
    cmd.Parameters.Add("@File_Code", SqlDbType.VarChar);    
    cmd.Parameters["@File_Code"].Value = item;    
    cmd.Parameters.Add("@Dept_Code", SqlDbType.VarChar);    
    cmd.Parameters["@Dept_Code"].Value = DropDownList1.Text;        
    cmd.ExecuteNonQuery();
}

Когда вы получаете ошибку IConvertable, это означает, что вы пытались присвоить один тип другому. В вашем случае я бы предположил, что вы пытались присвоить текстовое поле для строки. Текстовое поле является объектом. Вам нужно выбрать значение из него и преобразовать этот ToString().

Например, если вы хотите назначить текстовое поле для строки, это будет выглядеть так:

myString = Textbox1.Value.ToString();

IConvertable - это неявный ToString (), который вы иногда можете использовать. Не все это реализовано. В вашем случае, для каждого элемента управления, который вы назначаете строке, убедитесь, что на выходе будет строка, которую вы хотите. Некоторые будут реализовывать ToString (), и это будет просто индикатор используемого вами элемента управления, а не значение, которое вы ожидаете. Посмотрите на каждый элемент и посмотрите, где хранятся данные, которые вы хотите (обычно в свойстве с именем Текст или Значение). Затем проверьте тип данных для этого вывода.

Я хотел добавить это, потому что я столкнулся с этим сообщением об ошибке сегодня, но на самом деле это было просто замаскирование более глубокой основной проблемы.

Я работал с некоторыми обобщениями и рефлексией, и после того, как копать дальше, реальная ошибка была The type 'Microsoft.SqlServer.Types.SqlGeography' exists in both 'Microsoft.SqlServer.Types.dll' and 'Microsoft.SqlServer.Types.dll',

Решение состояло в том, чтобы выровнять версии DLL, на которые ссылается мое приложение, и зависимости. Я сделал это, установив конкретную версию от Nuget, и проблема решена! Если это не вариант, вы можете использовать связывание перенаправлений, но я не пробовал.

Надеюсь, что это помогает кому-то еще!

Я смог решить проблему, основываясь на совете Александра.

Пожалуйста, найдите правильный код ниже.

Спасибо за Александра и всех остальных за их помощь специально Абдулу, который провел много времени.

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Specialized;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Data.SqlClient;
using System.Web.UI.HtmlControls;

public partial class FileIDmasterWorking : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
    }

    protected void Button4_Click(object sender, EventArgs e)
    {
        int myint = Convert.ToInt32(TextBox1.Text) + 1;

        for (int i = 1; i < myint; i++)
        {
            Convert.ToString(ListBox2.Items);

            ListBox2.Items.Add(DropDownList1.SelectedItem.ToString() + i.ToString());

        }
    }

    private string GetConnectionString()
    {
        return     System.Configuration.ConfigurationManager.ConnectionStrings["RM_Jan2011ConnectionString"].ConnectionString;
    }

    private void InsertRecords(StringCollection sc)
    {
        SqlConnection conn = new SqlConnection(GetConnectionString());

        StringBuilder sb = new StringBuilder(string.Empty);

        **foreach (ListItem item in ListBox2.Items)
        {
            const string sqlStatement = "INSERT INTO FileID(File_Code, Dept_Code) VALUES(@File_Code, @Dept_Code)";
            sb.AppendFormat("{0}('{1}'); ", sqlStatement, item);
            SqlCommand cmd = new SqlCommand(sqlStatement, conn);
            cmd.Parameters.Add("@File_Code", SqlDbType.VarChar);
            cmd.Parameters["@File_Code"].Value = item.ToString();
            cmd.Parameters.Add("@Dept_Code", SqlDbType.VarChar);
            cmd.Parameters["@Dept_Code"].Value = DropDownList1.Text;
            conn.Open();
            cmd.ExecuteNonQuery();**

            Page.ClientScript.RegisterClientScriptBlock(typeof(Page), "Script", "alert('Records Successfuly Saved!');", true);

            conn.Close();
        }
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        StringCollection sc = new StringCollection();

        foreach (ListItem item in ListBox2.Items)
        {
            {
                sc.Add(item.Text);
            }
        }

        InsertRecords(sc);
    }

}

Вместо

cmd.Parameters["@File_Code"].Value = ListBox2.Items;

попробуй сделать

cmd.Parameters["@File_Code"].Value = ListBox2.SelectedItem.Text;

поскольку ListBox.Items является коллекцией, и вам нужно конкретное значение, а не группа значений.

Неправильный код

foreach (string item in sc)
    {
        const string sqlStatement = "INSERT INTO FileID(File_Code, Dept_Code) VALUES(@File_Code, @Dept_Code)";

        sb.AppendFormat("{0}('{1}'); ", sqlStatement, item);

    }

Делать

string sqlStatement = string.Empty; 
foreach (string item in sc)
    {
        sqlStatement = "INSERT INTO FileID(File_Code, Dept_Code) VALUES({0}, {1})";

      sqlStatement = string.Format(sqlStatement, fileCodeVar, deptCodeVar);//let fileCodeVar is a variable containing fileCode and DeptCodeVar is a variable containing DeptCode

    }

замещать

SqlCommand cmd = new SqlCommand(sb.ToString(), conn);

С

 SqlCommand cmd = new SqlCommand(sqlStatement, conn);

Я знаю, что это немного устарело, однако у меня есть другое решение, если кто-то его ищет.

Столбец TIME в БД и запрос выбора, я получил аналогичную ошибку. Для модели я использовал строку в качестве типа времени.

Просто CAST в SQL введите TIME или любой другой тип как VARCHAR(8) или VARCHAR(требуемая длина).

Другие вопросы по тегам