[Mono-list] DBNull value causes InvalidCastException

Daniel Morgan danmorg@sc.rr.com
Fri, 24 Jan 2003 17:38:43 -0500

pdate of /cvs/public/mcs/class/System.Data/System.Data
In directory mono-cvs.ximian.com:/tmp/cvs-serv4608/System.Data
Hi avd,

I made some changes to for DBNull and other things for setting of
DataRow.ItemArray to
work correctly.  I based it on how .NET works and MSDN docs.

Modified Files:
	DataColumn.cs DataRow.cs DataColumnCollection.cs
Log Message:
2003-01-24  Daniel Morgan <danmorg@sc.rr.com>

	* System.Data/DataColumn.cs: fixes to be like .NET -
	when setting AllowDBNull to false, determine if there is
	any data that has DBNull.Value, implement AutoIncrement, do not
	allow changing the DataType of the column if data has already been
	set, check if the DataType is supported,

	* System.Data/DataColumnCollection.cs: handle default ColumnName
	like .NET

	* System.Data/DataRow.cs: fixes to be like .NET - a
	data column gets initialized to all DBNull.Values not null,
	implement AutoIncrement, when setting ItemArray if the item array being
	set has less items than the number of columns in the table set those last
	columns to DBNull.Value, after setting ItemArray values do an EndEdit(),
	both a null and DBNull.Value get set to a DBNull.Value, only use
	and AutoIncrement if the value is set to null while DBNull.Value only gets
	to DBNull.Value


-----Original Message-----
From: mono-list-admin@ximian.com [mailto:mono-list-admin@ximian.com]On
Behalf Of Aleksey Demakov
Sent: Tuesday, January 21, 2003 2:25 PM
To: mono-list@ximian.com
Subject: [Mono-list] DBNull value causes InvalidCastException

Hi all,

While working with Virtuoso .NET data provider I run
across a case when filling a dataset with data from
a table produces InvalidCastException.

The investigation has shown that it was caused by the
following code fragment in the DataRow.cs:

> if (value[i] == null)
> {
> 	if (!_table.Columns[i].AllowDBNull)
> 		throw new NoNullAllowedException ();
> 	continue;
> }
> //FIXME: int strings can be converted to ints
> if (_table.Columns[i].DataType != value[i].GetType())
> 	throw new InvalidCastException ();

You can see that the code checks for null value
but not for DBNull. I'm not sure if null may
be used as DBNull. So perhaps the null check has to
be replaced DBNull check. However, I only added
the DBNull check for the existing one.

The patch is in the attached file.

BTW, for DBNull comparison I've used the following

   value[i] == DBNull.Value

I don't know if it is the most correct way. It might
be that a more correct way is something like

   Convert.IsDBNull (value[i])

The mono implementation of Convert.IsDBNull does
essentially the same, but I've taken a look into
rotor and its implementation of Convert.IsDBNull
returns true if value[i] is equal to DBNull.Value
OR if it is a IConvertible and IConvertible.GetTypeCode()
is equal to TypeCode.DBNull.