Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 对包含数值的字符串字段使用datareader.getString()时出现InvalidCastException_C#_Sqlite_System.data.sqlite - Fatal编程技术网

C# 对包含数值的字符串字段使用datareader.getString()时出现InvalidCastException

C# 对包含数值的字符串字段使用datareader.getString()时出现InvalidCastException,c#,sqlite,system.data.sqlite,C#,Sqlite,System.data.sqlite,我在sqlite数据库中有一个字段,我们将其称为field1,我试图在其上迭代每个记录(有一千多条记录)。字段类型为string。前四行中field1的值如下: DEPARTMENT 09:40:24 PARAM 350297 下面是我用来迭代每一行并显示值的一些简单代码: while (sqlite_datareader.Read()) { strVal = sqlite_datareader.GetString(0); Console.WriteLine(strVal)

我在sqlite数据库中有一个字段,我们将其称为
field1
,我试图在其上迭代每个记录(有一千多条记录)。字段类型为
string
。前四行中
field1
的值如下:

DEPARTMENT
09:40:24
PARAM
350297
下面是我用来迭代每一行并显示值的一些简单代码:

while (sqlite_datareader.Read())
{
     strVal = sqlite_datareader.GetString(0);
     Console.WriteLine(strVal);
}
前3个值显示正确。但是,当它到达数字条目350297时,它会出错,并在
.getString()
方法上出现以下异常

An unhandled exception of type 'System.InvalidCastException' occurred in System.Data.SQLite.dll
我试过用一根弦和一堆其他的东西。但我无法弄清为什么会发生这种情况。现在,我不得不使用
getValue
,它的类型是
object
,然后转换回字符串。但是我想弄清楚为什么
getString()
在这里不起作用

有什么想法吗

编辑:以下是我目前处理该问题的方式:

 object objVal;  // This is declared before the loop starts...

 objVal = sqlite_datareader.IsDBNull(i) ? "" : sqlite_datareader.GetValue(i);
 if (objVal != "")
 {
     strVal = (string)objVal;
 } 

这个问题应该包括的是

  • 表架构,最好是用于定义表的CREATETABLE语句
  • 用于打开sqlite\u数据读取器的SQL语句
  • 在处理数据库中的数据类型问题时,谨慎的做法是包含此类信息。否则,当模式DDL中显式定义了非常有用、关键的信息时,就会有很多不必要的猜测和纠结(如注释中所示)。获取数据的底层查询可能不那么重要,但如果存在可能影响返回类型的CAST语句和/或其他表达式,那么它很可能是问题的一部分。如果我在自己的系统上调试这个问题,我会首先检查这些


    这些评论包含了很好的讨论,但最好的解决方案是理解如何直接从官方文档中获取信息。关键在于sqlite定义了列上的类型亲缘关系,然后根据一组有限的存储类存储实际值。类型关联是数据在存储之前将尝试转换为的类型。但是(从文件中)

    这里的重要思想是推荐类型,而不是必需类型。任何列仍然可以存储任何类型的数据

    但是现在考虑……/P> 具有文本相关性的列使用存储类NULL、TEXT或BLOB存储所有数据。如果数字数据插入到具有文本关联性的列中,则在存储之前会将其转换为文本形式

    因此,即使任何存储类的值可以存储在任何列中,默认行为应该是在存储值之前将任何数值(如
    350297
    )转换为字符串。。。如果列正确声明为文本类型

    但是如果你仔细阅读,你最终会在第3.1.1节的末尾看到以下内容。关联名称示例:

    并且声明的“STRING”类型与数值关联,而不是与文本关联。

    因此,如果问题的详细信息按字面理解,并且
    field1
    的定义类似于
    field1 STRING
    ,那么从技术上讲,它具有数值亲缘关系,因此
    350297
    这样的值将被存储为整数,而不是字符串。问题中描述的行为正是将数据检索到严格类型的数据模型(如
    System.data.SQLite
    )时所期望的

    对这样一个不直观的设计决策很容易咒骂,我不会为这种行为辩护,但是

  • 至少明确说明了“字符串”类型的结果,以便可以将列重新定义为文本,以解决问题,以及
  • “字符串”实际上不是标准的SQL数据类型。SQL字符串由TEXT、NTEXT、CHAR、NCHAR、VARCHAR、NVARCHAR等定义
  • 解决方案是要么使用当前实现的代码:将所有值作为对象获取,然后转换为字符串值。。。对于.Net对象,这应该是普遍可行的,因为它们都应该定义
    ToString()
    方法

    或者,重新定义列,使其具有文本相似性,如

    CREATE TABLE myTable (
       ...
       field1 TEXT,
       ...
    )
    

    确切地说,如何重新定义充满数据的现有列是另一个问题。但是,至少在执行从原始列到新列的转换时,请记住使用
    CAST(field1作为文本)
    以确保现有数据的存储类已更改。(我不确定在将数据从现有表复制/插入到另一个表时是否“强制”类型关联,或者原始存储类是否默认保留。这就是我建议强制转换为文本值的原因。)

    对于整数类型,是否尝试了GetInt()而不是GetString()?GetValue(index).GetType()返回什么?该列中实际值的类型是什么?@EdPlunkett我无法切换到GetInt(),因为它是数据库中的字符串数据类型。当我按照您的建议运行
    GetType
    时,每种类型都解析为
    System.String
    我几乎感觉到这里有一些固有的缺陷…例外情况是告诉您,您正在尝试将某些内容转换为非字符串的字符串。可能是它的
    DBNull.Value
    。我不知道。但这不是一根绳子。您可以使用GetValue()来找出它实际上是什么,并采取相应的行动。如何“转换回字符串”
    (字符串)obj
    ,或
    System.Convert.ToString()
    ?就“固有缺陷”而言,在很大程度上,在那里执行的测试最少、理解最差的代码是您自己的,并且是由经验最少的开发人员编写的。。。。我之所以问这个问题,是因为即使您的sqllite列被定义为一个字符串,方法
    sqlite\u datareader.GetString()
    似乎也是