简体   繁体   English

C# 将数据添加到 SQL 表“指定的转换无效。”

[英]C# adding data to a SQL table “Specified cast is not valid.”

C# adding data to a SQL table with ASP.NET throws an error C# 用ASP.NET向SQL表添加数据报错

System.InvalidCastException: "Specified cast is not valid" System.InvalidCastException:“指定的转换无效”

This is for a foreign key column with a data type of bigint.这是针对数据类型为 bigint 的外键列。

I set my type in C# to be Int64, after int definition threw an error but still get the error.我在 C# 中将我的类型设置为 Int64,在 int 定义抛出错误但仍然得到错误之后。

Is this because I can't add to a column that has foreign keys?这是因为我无法添加到具有外键的列吗? Do I need to cascade?我需要级联吗?

This is my datacontroller:这是我的数据控制器:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using SchoolDb.Models;
using MySql.Data.MySqlClient;
using System.Diagnostics;

namespace SchoolDb.Controllers
{
    public class CoursesDataController : ApiController
    {
        private SchoolDbContext School = new SchoolDbContext();

        /// <summary>
        /// returns list of courses in the system
        /// </summary>
        /// <example>GET api/CoursesData/ListCourses</example>
        /// <returns>a list of courses</returns>
        [HttpGet]
        [Route("api/CourseData/ListCourses/{SearchKey?}")]
        public IEnumerable<Course> ListCourses(string SearchKey = null)
        {
            //create an instance of a connection
            MySqlConnection Conn = School.AccessDatabase();

            //open the connection between server and database
            Conn.Open();

            string query = "Select * from classes where lower(classname) like lower(@key) or classid like (@key)";
            Debug.WriteLine("the search key is " + query);

            // establish a new command query for our database
            MySqlCommand cmd = Conn.CreateCommand();

            // SQL query
            cmd.CommandText = query;
            cmd.Parameters.AddWithValue("@key", "%" + SearchKey + "%");
            cmd.Prepare();

            // gather result set of query into variable
            MySqlDataReader ResultSet = cmd.ExecuteReader();

            // create an empty list of courses
            List<Course> Courses = new List<Course> { };

            while (ResultSet.Read())
            {
                // access column information by the db column name as an index
                int ClassId = (int)ResultSet["classid"];
                string ClassCode = (string)ResultSet["classcode"];
                Int64 TeacherId = (Int64)ResultSet["teacherid"];
                DateTime StartDate = (DateTime)ResultSet["startdate"];
                DateTime FinishDate = (DateTime)ResultSet["finishdate"];
                string ClassName = (string)ResultSet["classname"];

                Course NewCourse = new Course();
                NewCourse.ClassId = ClassId;
                NewCourse.ClassCode = ClassCode;
                NewCourse.TeacherId = TeacherId;
                NewCourse.StartDate = StartDate;
                NewCourse.FinishDate = FinishDate;
                NewCourse.ClassName = ClassName;

                // add the course info to the list
                Courses.Add(NewCourse);
            }

            Conn.Close();

            // return the final list of courses
            return Courses;
        }

        /// <summary>
        /// returns a single instance of a course
        /// </summary>
        /// <param name="id">class id</param>
        /// <returns>info on a particular course based on classid input</returns>
        [HttpGet]
        public Course FindCourse(int id)
        {
            Course NewCourse = new Course();

            // create an instance of a connection
            MySqlConnection Conn = School.AccessDatabase();

            // open the connection between server and database
            Conn.Open();

            // establish a new command query for our database
            MySqlCommand cmd = Conn.CreateCommand();

            // SQL query
            cmd.CommandText = "Select * from classes where classid = " + id;

            // gather result set of query into variable
            MySqlDataReader ResultSet = cmd.ExecuteReader();

            while (ResultSet.Read())
            {
                // access column information by the db column name as an index
                int ClassId = (int)ResultSet["classid"];
                string ClassCode = (string)ResultSet["classcode"];
                Int64 TeacherId = (Int64)ResultSet["teacherid"];
                DateTime StartDate = (DateTime)ResultSet["startdate"];
                DateTime FinishDate = (DateTime)ResultSet["finishdate"];
                string ClassName = (string)ResultSet["classname"];

                NewCourse.ClassId = ClassId;
                NewCourse.ClassCode = ClassCode;
                NewCourse.TeacherId = TeacherId;
                NewCourse.StartDate = StartDate;
                NewCourse.FinishDate = FinishDate;
                NewCourse.ClassName = ClassName;
            }

            return NewCourse;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <example>POST: /api/CoursesData/DeleteCourse/3</example>
        [HttpPost]
        public void DeleteCourse(int id)
        {
            // create an instance of a connection
            MySqlConnection Conn = School.AccessDatabase();

            // open the connection between server and database
            Conn.Open();

            // establish a new command query for our database
            MySqlCommand cmd = Conn.CreateCommand();

            // SQL query
            cmd.CommandText = "Delete from classes where classid=@id";
            cmd.Parameters.AddWithValue("@id", id);
            cmd.Prepare();

            cmd.ExecuteNonQuery();

            Conn.Close();
        }

        [HttpPost]
        public void AddCourse(Course NewCourse)
        {
            // create an instance of a connection
            MySqlConnection Conn = School.AccessDatabase();

            // open the connection between server and database
            Conn.Open();

            // establish a new command query for our database
            MySqlCommand cmd = Conn.CreateCommand();

            // SQL query
            cmd.CommandText = "insert into classes (classcode, teacherid, startdate, finishdate, classname) value (@ClassCode, @TeacherId, @StartDate,@FinishDate,@ClassName)";
            cmd.Parameters.AddWithValue("@ClassCode", NewCourse.ClassCode);
            cmd.Parameters.AddWithValue("@TeacherId", NewCourse.TeacherId);
            cmd.Parameters.AddWithValue("@StartDate", NewCourse.StartDate);
            cmd.Parameters.AddWithValue("@FinishDate",NewCourse.FinishDate );
            cmd.Parameters.AddWithValue("@ClassName", NewCourse.ClassName);
            cmd.Prepare();

            cmd.ExecuteNonQuery();

            Conn.Close();
        }
    }
}

You didn't specify which line the InvalidCastException occurs on, so I'm going to assume it's one of the following lines with explicit casts:您没有指定InvalidCastException发生在哪一行,所以我假设它是以下带有显式强制转换的行之一:

//access column information by the db column name as an index
int ClassId = (int)ResultSet["classid"];
string ClassCode = (string)ResultSet["classcode"];
Int64 TeacherId = (Int64)ResultSet["teacherid"];
DateTime StartDate = (DateTime)ResultSet["startdate"];
DateTime FinishDate = (DateTime)ResultSet["finishdate"];
string ClassName = (string)ResultSet["classname"];

One possibility is trying to retrieve an int from a long column, or vice versa.一种可能性是尝试从long列中检索int ,反之亦然。 This can be avoided by using the GetInt32 or GetInt64 method.这可以通过使用GetInt32GetInt64方法来避免。 These will convert the value to a smaller size if possible, otherwise throw an OverflowException .如果可能,这些会将值转换为较小的大小,否则抛出OverflowException

Another possibility is that some of the columns contain NULL .另一种可能性是某些列包含NULL In that case, ResultSet["Name"] will return DBNull.Value , which can't be cast to a string (or int or DateTime).在这种情况下, ResultSet["Name"]将返回DBNull.Value ,它不能转换为字符串(或 int 或 DateTime)。

Depending on what columns can contain NULL values, you likely need code similar to the following:根据哪些列可以包含NULL值,您可能需要类似于以下的代码:

//access column information by the db column name as an index
int ClassId = ResultSet.GetInt32("classid");
string ClassCode = ResultSet.IsDBNull("classcode") ? null : reader.GetString("classcode");
Int64 TeacherId = ResultSet.GetInt64("teacherid");
DateTime StartDate = (DateTime)ResultSet["startdate"];
DateTime FinishDate = (DateTime)ResultSet["finishdate"];
string ClassName = ResultSet.IsDBNull("classname") ? null : ResultSet.GetString("classname");

But I would recommend using an ORM like Dapper to simplify all of this code and map a DB row easily to a C# object.但我建议使用像Dapper这样的 ORM 来简化所有这些代码,并将 map 数据库行轻松转换为 C# object。

Hello there: An InvalidCastException basically is thrown when the conversion of an instance of one type to another type is not supported(and that is the definition of it).你好:当不支持将一种类型的实例转换为另一种类型时(这就是它的定义),基本上会抛出InvalidCastException For example, attempting to convert a Char value to a DateTime value throws an InvalidCastException exception.例如,尝试将 Char 值转换为 DateTime 值会引发 InvalidCastException 异常。 in your case I think first of all where you are casting "startdate" to DateTime you need to surround that whole code with a Try{}Catch(InvalidCastException ex){}.在你的情况下,我认为首先你需要将“startdate”转换为 DateTime,你需要用 Try{}Catch(InvalidCastException ex){} 包围整个代码。 Then for the actual problem I think you need to use var instead of DateTime or Int64 if you have a dought about the return type.然后对于实际问题,如果您对返回类型有疑问,我认为您需要使用 var 而不是 DateTime 或 Int64。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM