2

我正在编写一个非常简单的方法来将 csv 转换为数据表,以便可以将其插入 SQL 数据库。它完全按照它应该的方式工作,除非我尝试用 DBNull.Value 替换空字符串,否则它会引发 ArrayTypeMismatchException。传入的流是带有数据的简单逗号分隔文件。

问题代码:

public static DataTable StreamToTable(Stream stream, bool headersAvailable, bool convertBlankToDBNull)
    {

        DataTable data = new DataTable();
        StreamReader reader = new StreamReader(stream);

        if (!reader.EndOfStream)
        {
            if (headersAvailable)
            {
                try
                {
                    //get headers from first line
                    string[] headers = reader.ReadLine().Split(',');

                    //construct headers
                    for (int i = 0; i < headers.Length; i++)
                    {
                        data.Columns.Add(headers[i]);
                    }
                }
                catch (IOException ioEx)
                {
                    return null;
                }
            }

            while (!reader.EndOfStream)
            {
                object[] row = reader.ReadLine().Split(',');

                if (convertBlankToDBNull)
                {
                    for (int i = 0; i < row.Length; i++)
                    {
                        if (row[i].ToString().Equals(""))
                        {
                            row[i] = DBNull.Value; //this is where I get the exception
                        }
                    }
                }
                data.Rows.Add(row);
            }

            return data;
        }
        else return null;
    }

我不知道我做错了什么......我应该能够为数组分配任何东西,因为它是一个对象数组,那么怎么会有类型不匹配呢?

4

1 回答 1

2

您已经发现了不安全数组协方差的可怕之处。

row是一个string[]被不安全地强制转换为object[]. 即使该转换成功,该数组仍然是 a string[](因为这就是返回的内容) ,Split()并且不能用作. 特别是,它仍然无法容纳不是s 的东西。object[]
string

相反,您可以创建一个新的并用这些sobject[]填充它:string

object[] row = Array.ConvertAll(
    reader.ReadLine().Split(','),
    s => (object)s
);
于 2012-11-27T22:00:21.247 回答