Problem casting in mixed 1.1 and 2.0 environment

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hi,

I have this annoying problem with a cast failing from a DAL that was created
in 1.1 that I have included in a 2.0 app.

Every stored proc in our system uses an integer parameter to return an error
code. The following code works fine in 1.1 apps, and from a test app I made
in fully 2.0 apps. However, when I try to use the DAL from a 2.0 app that
uses the 1.1 compiled DAL, the following cast throws an invalid cast
exception (System.InvalidCastException: Specified cast is not valid.)

cmdToExecute.Parameters.Add(new SqlParameter("@iErrorCode", SqlDbType.Int,
4, ParameterDirection.Output, true, 10, 0, "", DataRowVersion.Proposed,
_errorCode));

con.Open();

// Execute query.
adapter.Fill(toReturn);
_errorCode = (Int32)cmdToExecute.Parameters["@iErrorCode"].Value;

Is anyone able to confirm if this is a bug in the Framework, expected
behaviour, or otherwise?

Regards
Mark
 
Tyler Durden said:
cmdToExecute.Parameters.Add(new SqlParameter("@iErrorCode", SqlDbType.Int, : :
_errorCode = (Int32)cmdToExecute.Parameters["@iErrorCode"].Value;

Is anyone able to confirm if this is a bug in the Framework, expected
behaviour, or otherwise?

What happens when you say,

cmdToExecute.Parameters["@iErrorCode"].Value.GetType( ).FullName

?

I believe under .NET 2.0, this will always be a SqlInt32 (which is Nullable, a
new concept in 2.0, thus whether it has a DBNull value or not, it will always
be this one specific type), distinguished from .NET 1.x where this parameter
value could be an Int32 or a DBNull.Value (i.e., the typing was up in the air
and I believe this led to less strongly-typed, less-efficient IL in 1.x.)


Derek Harmon
 
Hi Derek

If I understand what you are saying correctly, I would think that would mean
the cast would not work in the 2.0 environment either. The fact is that it
does work when in a completely 1.1 compiled app, and also in a completely 2.0
compiled app, but not when use a mixture of both.

Therefore, from your response I would assume that a cast of that type would
not succeed in the 2.0 framework because of the stronger typing rules. Or am
I missing something?

Regards,
Mark

Derek Harmon said:
Tyler Durden said:
cmdToExecute.Parameters.Add(new SqlParameter("@iErrorCode", SqlDbType.Int, : :
_errorCode = (Int32)cmdToExecute.Parameters["@iErrorCode"].Value;

Is anyone able to confirm if this is a bug in the Framework, expected
behaviour, or otherwise?

What happens when you say,

cmdToExecute.Parameters["@iErrorCode"].Value.GetType( ).FullName

?

I believe under .NET 2.0, this will always be a SqlInt32 (which is Nullable, a
new concept in 2.0, thus whether it has a DBNull value or not, it will always
be this one specific type), distinguished from .NET 1.x where this parameter
value could be an Int32 or a DBNull.Value (i.e., the typing was up in the air
and I believe this led to less strongly-typed, less-efficient IL in 1.x.)


Derek Harmon
 
Derek,

SqlInt32 was in the framework before 2.0, and it is different from a
Nullable<int>. SqlInt32 is a structure that is very similar, but not the
same as what is considered a Nullable type in 2.0.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Derek Harmon said:
Tyler Durden said:
cmdToExecute.Parameters.Add(new SqlParameter("@iErrorCode",
SqlDbType.Int, : :
_errorCode = (Int32)cmdToExecute.Parameters["@iErrorCode"].Value;

Is anyone able to confirm if this is a bug in the Framework, expected
behaviour, or otherwise?

What happens when you say,

cmdToExecute.Parameters["@iErrorCode"].Value.GetType( ).FullName

?

I believe under .NET 2.0, this will always be a SqlInt32 (which is
Nullable, a
new concept in 2.0, thus whether it has a DBNull value or not, it will
always
be this one specific type), distinguished from .NET 1.x where this
parameter
value could be an Int32 or a DBNull.Value (i.e., the typing was up in the
air
and I believe this led to less strongly-typed, less-efficient IL in 1.x.)


Derek Harmon
 
Mark,

I think the problem here is the fact that you are using the SqlParameter
class which is compiled against 2.0 and passing it to a version that expects
the 1.1 version of SqlParameter. If this is the case, then you have no
choice but to re-compile your DAL against 2.0 if you hope to use it with
2.0.

Hope this helps.
 
Thanks Nicholas

I was afraid of something like that. Means we now have to maintain 2
versions for the old 1.1 apps. I was hoping that it was something stupid that
wasn't being done correctly.

Thanks again.
Mark

Nicholas Paldino said:
Mark,

I think the problem here is the fact that you are using the SqlParameter
class which is compiled against 2.0 and passing it to a version that expects
the 1.1 version of SqlParameter. If this is the case, then you have no
choice but to re-compile your DAL against 2.0 if you hope to use it with
2.0.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Tyler Durden said:
Hi,

I have this annoying problem with a cast failing from a DAL that was
created
in 1.1 that I have included in a 2.0 app.

Every stored proc in our system uses an integer parameter to return an
error
code. The following code works fine in 1.1 apps, and from a test app I
made
in fully 2.0 apps. However, when I try to use the DAL from a 2.0 app that
uses the 1.1 compiled DAL, the following cast throws an invalid cast
exception (System.InvalidCastException: Specified cast is not valid.)

cmdToExecute.Parameters.Add(new SqlParameter("@iErrorCode", SqlDbType.Int,
4, ParameterDirection.Output, true, 10, 0, "", DataRowVersion.Proposed,
_errorCode));

con.Open();

// Execute query.
adapter.Fill(toReturn);
_errorCode = (Int32)cmdToExecute.Parameters["@iErrorCode"].Value;

Is anyone able to confirm if this is a bug in the Framework, expected
behaviour, or otherwise?

Regards
Mark
 
Hi,

// Execute query.
adapter.Fill(toReturn);
_errorCode = (Int32)cmdToExecute.Parameters["@iErrorCode"].Value;

Have you trying to see the type it's returning? , something like:

object o = cmdToExecute.Parameters["@iErrorCode"].Value;

and placing a breakpoint after it.
 
Mark,

I'm pretty sure that is what it is now. Because your interface to your
assemblies are using exposing framework classes, and those classes have
changed (especially SqlParameter, I believe that the inheritance heiarchy
has been changed), your classes are expecting a type signature that is
inhernently different than what 2.0 is offering up.

Why not just move to 2.0?


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Tyler Durden said:
Thanks Nicholas

I was afraid of something like that. Means we now have to maintain 2
versions for the old 1.1 apps. I was hoping that it was something stupid
that
wasn't being done correctly.

Thanks again.
Mark

Nicholas Paldino said:
Mark,

I think the problem here is the fact that you are using the
SqlParameter
class which is compiled against 2.0 and passing it to a version that
expects
the 1.1 version of SqlParameter. If this is the case, then you have no
choice but to re-compile your DAL against 2.0 if you hope to use it with
2.0.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Tyler Durden said:
Hi,

I have this annoying problem with a cast failing from a DAL that was
created
in 1.1 that I have included in a 2.0 app.

Every stored proc in our system uses an integer parameter to return an
error
code. The following code works fine in 1.1 apps, and from a test app I
made
in fully 2.0 apps. However, when I try to use the DAL from a 2.0 app
that
uses the 1.1 compiled DAL, the following cast throws an invalid cast
exception (System.InvalidCastException: Specified cast is not valid.)

cmdToExecute.Parameters.Add(new SqlParameter("@iErrorCode",
SqlDbType.Int,
4, ParameterDirection.Output, true, 10, 0, "", DataRowVersion.Proposed,
_errorCode));

con.Open();

// Execute query.
adapter.Fill(toReturn);
_errorCode = (Int32)cmdToExecute.Parameters["@iErrorCode"].Value;

Is anyone able to confirm if this is a bug in the Framework, expected
behaviour, or otherwise?

Regards
Mark
 
Hi Ignacio

I did previously look at that and confirmed it was a SqlInt32, not null etc.
You did make me think to try something which was to do the following:

// Execute query.
adapter.Fill(toReturn);
SqlInt32 paramValue = (SqlInt32)cmdToExecute.Parameters["@iErrorCode"].Value;
_errorCode = (Int32)paramValue;

Doing this, the code successfully casts the value.

Thanks Mark.


Ignacio Machin ( .NET/ C# MVP ) said:
Hi,

// Execute query.
adapter.Fill(toReturn);
_errorCode = (Int32)cmdToExecute.Parameters["@iErrorCode"].Value;

Have you trying to see the type it's returning? , something like:

object o = cmdToExecute.Parameters["@iErrorCode"].Value;

and placing a breakpoint after it.
 
Hi again Nicholas

If you read my reply to Ignacio's post, I think what you are saying is the
most likely reason. We are moving to 2.0 but still have a couple of apps
that are 1.1 and will take a little longer to convert. If I can modify the
DAL to use the code I did to test Ignacio's suggestion then maybe I can get
away with not having to make and maintain 2 versions.

Thanks again
Mark

Nicholas Paldino said:
Mark,

I'm pretty sure that is what it is now. Because your interface to your
assemblies are using exposing framework classes, and those classes have
changed (especially SqlParameter, I believe that the inheritance heiarchy
has been changed), your classes are expecting a type signature that is
inhernently different than what 2.0 is offering up.

Why not just move to 2.0?


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Tyler Durden said:
Thanks Nicholas

I was afraid of something like that. Means we now have to maintain 2
versions for the old 1.1 apps. I was hoping that it was something stupid
that
wasn't being done correctly.

Thanks again.
Mark

Nicholas Paldino said:
Mark,

I think the problem here is the fact that you are using the
SqlParameter
class which is compiled against 2.0 and passing it to a version that
expects
the 1.1 version of SqlParameter. If this is the case, then you have no
choice but to re-compile your DAL against 2.0 if you hope to use it with
2.0.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Hi,

I have this annoying problem with a cast failing from a DAL that was
created
in 1.1 that I have included in a 2.0 app.

Every stored proc in our system uses an integer parameter to return an
error
code. The following code works fine in 1.1 apps, and from a test app I
made
in fully 2.0 apps. However, when I try to use the DAL from a 2.0 app
that
uses the 1.1 compiled DAL, the following cast throws an invalid cast
exception (System.InvalidCastException: Specified cast is not valid.)

cmdToExecute.Parameters.Add(new SqlParameter("@iErrorCode",
SqlDbType.Int,
4, ParameterDirection.Output, true, 10, 0, "", DataRowVersion.Proposed,
_errorCode));

con.Open();

// Execute query.
adapter.Fill(toReturn);
_errorCode = (Int32)cmdToExecute.Parameters["@iErrorCode"].Value;

Is anyone able to confirm if this is a bug in the Framework, expected
behaviour, or otherwise?

Regards
Mark
 
Hi,

Tyler Durden said:
Hi Ignacio

I did previously look at that and confirmed it was a SqlInt32, not null
etc.
You did make me think to try something which was to do the following:

// Execute query.
adapter.Fill(toReturn);
SqlInt32 paramValue =
(SqlInt32)cmdToExecute.Parameters["@iErrorCode"].Value;
_errorCode = (Int32)paramValue;

Doing this, the code successfully casts the value.

Maybe cause Paldino's suggestion

Out of curiosity, did you tried Convert.ToInt32 ?
 
Back
Top