简体   繁体   中英

How can I add a type parameter to my DAL's implementation of ExecuteScalar?

So as everyone knows, .NET's SqlClient class offers as a way of getting data from the database the ExecuteScalar method, which returns an object . While it's not a big deal to just cast appropriately, I wanted to write a strongly typed version that returns a properly typed object. So, I wrote the following C#:

public T ExecuteScalar<T>(IDbCommand cmd) where T : struct
{
    cmd.Connection = this.conn;
    object o = cmd.ExecuteScalar();
    return (T)o;
}

This works very well for booleans and DateTime s. However, for integers, it throws an InvalidCastException . So, I did what anyone armed with a copy of Reflector would do and dove into the Field<T>(this DataRow, string columnName) extension method. I ripped out the internal class that it uses to convert values to the requested type and tested. However, for value types, the code is just return (T)value; - which is of course not helpful.

So, my question: anyone have any thoughts about how I can get my method to properly return values for all value types and strings? Even just string, boolean, DateTime and int would be fine.

Thanks in advance!

Your query is returning a boxed instance of a different numeric type (probably decimal ).

You cannot unbox it and convert it to int in one operation .

Instead, you can call Convert.ChangeType :

return o is t ? (T)o : (T)Convert.ChangeType(o, typeof(T));

Looking at your code the cast should be OK, if the value returned is in fact an integer.

Perhaps your database returns NULL ? In that case, o will be DBNull.Value , which you will have to take into account before casting. An easy way would be to use int? , or you could decide to throw an exception in that case.

If null is not the issue, then try posting the concrete type of o after the ExceuteScalar call.

If the object returned was not an integer (if it is a float, double, byte, etc) it was boxed to an object and can only be cast back to its original type. check the type of o .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM