开发者

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

开发者 https://www.devze.com 2023-01-27 12:51 出处:网络
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,

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 DateTimes. However, f开发者_如何学Cor 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消