如何在DAL的ExecuteScalar实现中添加类型参数?

时间:2010-11-28 16:59:27

标签: c# .net generics ado.net

众所周知,.NET的SqlClient类提供了一种从数据库中获取ExecuteScalar方法的数据的方法,该方法返回object。虽然只是适当地进行投射并不是什么大问题,但我想编写一个强类型版本,它返回一个正确类型的对象。所以,我写了下面的C#:

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

这对布尔人和DateTime非常有效。但是,对于整数,它会抛出InvalidCastException。所以,我做了任何拥有Reflector副本的人都会做的事情并且进入Field<T>(this DataRow, string columnName)扩展方法。我撕掉了用于将值转换为请求类型并进行测试的内部类。但是,对于值类型,代码只是return (T)value; - 这当然没有帮助。

所以,我的问题:任何人都有任何想法如何让我的方法正确返回所有值类型和字符串的值?即使只是字符串,布尔值,DateTime和int也没关系。

提前致谢!

3 个答案:

答案 0 :(得分:3)

您的查询返回一个不同数字类型的盒装实例(可能是decimal)。

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

相反,您可以致电Convert.ChangeType

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

答案 1 :(得分:0)

如果返回的值实际上是整数,那么查看代码时,强制转换应该没问题。

也许您的数据库返回NULL?在这种情况下,o将为DBNull.Value,您必须在投射前考虑这一点。一种简单的方法是使用int?,或者您可以决定在这种情况下抛出异常。

如果null不是问题,那么尝试在ExceuteScalar调用之后发布具体类型的o。

答案 2 :(得分:0)

如果返回的对象不是整数(如果它是float,double,byte等),则它被装箱到一个对象,并且只能被转换回其原始类型。检查o的类型。