我正在编写一个非常简单的方法,将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;
}
我无法弄清楚我做错了什么......我应该能够为数组分配任何东西,因为它是一个对象数组,那么怎么会出现类型不匹配?
答案 0 :(得分:2)
你发现了unsafe array covariance的恐怖。
row
是string[]
,已被不安全地投射到object[]
。即使该转换成功,该数组仍然是string[]
(因为这是Split()
返回的内容),并且不能使用作为object[]
。
特别是,它仍然无法容纳不是string
的东西。
相反,您可以创建一个新的object[]
并使用string
s填充它:
object[] row = Array.ConvertAll(
reader.ReadLine().Split(','),
s => (object)s
);