I am writing a very simple method to convert a csv to a datatable so it can be inserted into a SQL database. It works exactly how it should, unless I try to replace empty strings with DBNull.Value, then it throws an ArrayTypeMismatchException. The stream coming in is a simple comma-separated file with the data.
The problem code:
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;
}
I can’t figure out what I am doing wrong… I should be able to assign anything to the array because it’s an object array, so how can there be a type mismatch?
You’ve discovered the horrors of unsafe array covariance.
rowis astring[]that has been unsafely cast toobject[]. Even though that cast succeeds, the array is still astring[](since that’s whatSplit()returns), and cannot be used as anobject[].In particular, it still can’t hold things that aren’t
strings.Instead, you can create a new
object[]and populate it with thosestrings: