假设我在名为MyTable
的SQL Server数据库中有一个名为MyDB
的表,其中包含以下三个记录:
|ID|MyVarcharColumn|
--------------------
|1|123|
|2|2014-10-01 9:58 AM|
|3|True|
现在假设我有以下VB.NET代码:
Public Shared Sub Test()
Dim myIntValue As Integer = GetValue(Of Integer)(1)
Dim myDateValue As Date = GetValue(Of Date)(2)
Dim myBooleanValue As Boolean = GetValue(Of Boolean)(3)
End Sub
Public Shared Function GetValue(Of T)(ByVal id As Integer) As T
Dim ds As System.Data.DataSet = GetSQLDataSet(String.Format("SELECT MyVarcharColumn FROM MyTable WHERE ID={0}", id))
Return CType(ds.Tables(0).Rows(0).Item("MyVarcharColumn"), T)
End Function
Public Shared Function GetSQLDataSet(ByVal ForQuery As String) As DataSet
GetSQLDataSet = New DataSet()
Dim conn As New System.Data.SqlClient.SqlConnection("Data Source=MyDBServer;Initial Catalog=MyDB;Integrated Security=True")
Dim cmd As New System.Data.SqlClient.SqlCommand(ForQuery, conn)
conn.Open()
Dim da As New System.Data.SqlClient.SqlDataAdapter(cmd)
da.Fill(GetSQLDataSet)
conn.Close()
End Function
我可以致电Test()
,一切正常。值得注意的是,使用VB.NET的CType
函数以某种方式在转换(而不是 cast )中成功,因为底层数据库列值是一个字符串)进入正确的类型。
现在,如果我相信Correct C# conversion counterpart for VB's CTYPE()和How do I translate VB.Net's CType() to C#之类的内容,我应该可以使用以下C#代码:
static void Main(string[] args)
{
int myIntValue = GetValue<int>(1);
DateTime myDateValue = GetValue<DateTime>(2);
bool myBooleanValue = GetValue<bool>(3);
}
static T GetValue<T>(int id)
{
System.Data.DataSet ds = GetSQLDataSet(String.Format("SELECT MyVarcharColumn FROM MyTable WHERE ID={0}", id));
return (T)ds.Tables[0].Rows[0]["MyVarcharColumn"];
}
public static System.Data.DataSet GetSQLDataSet(string forQuery)
{
System.Data.DataSet ret = new System.Data.DataSet();
System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection("Data Source=MyDBServer;Initial Catalog=MyDB;Integrated Security=True");
System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(forQuery, conn);
System.Data.SqlClient.SqlDataAdapter da = new System.Data.SqlClient.SqlDataAdapter(cmd);
conn.Open();
da.Fill(ret);
conn.Close();
return ret;
}
但是,我在运行时遇到错误return (T)ds.Tables[0].Rows[0]["MyVarcharColumn"];
说&#34;指定演员表无效&#34;。
我知道我没有投出,因为返回类型是一个字符串,所以我真正需要的是转换。在VB.NET中,CType
函数既有角色,也有角色。但是,在C#中,似乎我使用了Convert.ToInt32()
之类的显式类型转换函数。由于我在这里处理泛型类型,因此无效。
我想如果我可以把它归结为一个问题,那就是:在C#中,如何将字符串转换为像VB.NET CType
这样的泛型类型?
答案 0 :(得分:1)
如果仅需要支持其支持的一组非常具体的类型,那么Convert.ChangeType
可能没问题:
object value = (string) ds.Tables[0].Rows[0]["MyVarcharColumn"];
return (T) Convert.ChangeType(value, typeof(T));
您可能还需要考虑指定格式提供程序。我会强烈鼓励你避免这种代码。例如,您对double
值的期望是什么?那么DateTime
呢?理想情况下,您可以将这些存储在SQL中的不同列中,这样您就可以避免自己进行任何转换 - 但如果您必须使用字符串,我可能会非常明确地使用它。格式化和解析,例如使用ISO-8601格式表示DateTime
值。你目前的做法使文化问题变得非常脆弱。
我还强烈建议您停止动态构建SQL。即使是整数也不理想,因为你没有指定格式提供者,但在所有案例中使用参数化SQL只是一个很好的习惯。