I’m having some trouble with an application that we’re porting to Mono.
(For reference, the .NET runtime is 4.0, and the mono version is 2.6.7.)
EDIT: This problem persists on Mono 2.10.2
As part of the startup of the application, it reads data into memory. For this part I’m just using in-line SQL commands, but for some reason, I’m seeing inconsistent behaviour on Linux/Mono (when the whole thing works in Windows/.NET).
I have a query that works fine in some scenarios, but not in others.
This particular example doesn’t work:
var cmd = new SqlCommand("SELECT ID, Name, VATTerritoryID, NativeCurrencyID FROM PricingZones", conn);
var reader = cmd.ExecuteReader();
var objectToLoad = new SomeObjectType();
while (reader.Read())
{
objectToLoad.Property1 = reader.GetInt32(row.GetOrdinal("ID"));
objectToLoad.Property2 = reader.GetString(row.GetOrdinal("Name"));
objectToLoad.Property3 = reader.GetInt32(row.GetOrdinal("VATTerritoryID"));
objectToLoad.Property3 = reader.GetInt32(row.GetOrdinal("NativeCurrencyID"));
}
EDIT: For comparison, here’s one that does work:
var cmd = new SqlCommand("SELECT VATTerritoryID, ProductDescriptionID, VATBandID FROM VATTerritoryBandExceptions", conn);
var reader = cmd.ExecuteReader();
var someOtherObjectToLoad = new SomeOtherObjectType();
while (reader.Read())
{
someOtherObjectToLoad.Property1 = reader.GetInt32(row.GetOrdinal("VATTerritoryID"));
someOtherObjectToLoad.Property2 = reader.GetString(row.GetOrdinal("ProductDescriptionID"));
someOtherObjectToLoad.Property3 = reader.GetInt32(row.GetOrdinal("VATBandID"));
}
I had possible suspicions that there were differences down to:
- Casing (Since I know this is different on windows/linux), but putting everything to lowercase hasn’t solved the problem
- Column names (perhaps Mono cares more about reserved words?), but it seems replacing Name with [Name] or ‘Name’ didn’t make any different
The error I had in the first case was:
[IndexOutOfRangeException: Array index is out of range.]
at System.Data.SqlClient.SqlDataReader.GetInt32(Int32 i)
Suggesting that there is no “column1” in the returned result set.
(EDIT: updated this section a little for clarity)
Oddly, if I do this:
var cmd = new SqlCommand("SELECT ID, Name, VATTerritoryID, NativeCurrencyID FROM PricingZones", conn);
var reader = cmd.ExecuteReader();
var objectToLoad = new SomeObjectType();
while (reader.Read())
{
Console.WriteLine("First row, first column is " + row.GetValue(0));
Console.WriteLine("First row, second column is " + row.GetValue(1));
Console.WriteLine("First row, third column is " + row.GetValue(2));
Console.WriteLine("First row, fourth column is " + row.GetValue(3));
}
The output is:
First row, first column is 0
First row, second column is New
Array index is out of range.
I assume something strange is happening with the Mono framework in this case, but I can’t find a relevant bug report, and I can’t identify why this only happens in some cases but not others! Has anyone else had a similar experience?
EDIT: I’ve changed some of the statements to match those in the failing query exactly, in case there is an issue with reserved words or similar. Note that the query I’m issuing in the second case really does request four columns and seemingly only gets two very odd ones back (0 | New ).
Ok mate I managed to reproduce your problem. You have a threading problem there. That was my only idea what may be the cause of this problem and I managed to actually reproduce it.
In order to fix it you need to do the following:
Make sure every reader has a reader.Close() call after parsing the
data.
Use the following code to do thread-safe calls:
Looks like mono has a different implementation of SQL objects than .NET. It’s true that I wasn’t able to reproduce it on Windows!