我有以下方法:public static void Post(this DataRow dr, string tableName, SqlConnection conn)
我正在尝试为我的INSERT
构建一个DataRow
语句,但是我正在努力确定每列的数据类型以便正确格式化SQL语句。
我有这个:
public static void Post(this DataRow dr, string tableName, SqlConnection conn)
{
string sql = "INSERT INTO " + tableName + " VALUES(";
for (int i = 0; i < dr.ItemArray.Length; i++)
{
sql += "'" + dr[i].ToString() + "'";
if (i != dr.ItemArray.Length - 1)
sql += ",";
}
}
但表格中有很多日期和数字列,因此显然不是所有的值都可以包含在'
中。
我知道从DataTable
开始,您可以执行以下操作:myDt.Columns[0].Datatype
然后我可以使用它来分支逻辑并相应地格式化值但我似乎无法找到如何仅提供DataRow
时会访问此信息。
最糟糕的情况是,我可以重构应用程序,只需要DataTable
代替个人DataRow
,但这需要大量工作,所以我更喜欢找到一种方法按原样去做。
如果重要,这是一个winforms application / .NET 4.5
答案 0 :(得分:1)
如果您的DataRow
实际上已添加到方法之外的某些DataTable
行 - 那么您可以使用DataRow.Table属性访问它。
否则您可以使用dr[i].GetType()
并检查是DateTime还是数字。
答案 1 :(得分:1)
我认为,最好的OO Type-Safe方式是,您不应该通过直接SQL来执行。使用代表您的表格的实际C#类型创建POCO。
T Insert<T>(T classToBeInserted) //where T matches a table
T Select<T>(T classForClauses) //where T matches a table
如果您的通用T与表名匹配,并且类中的字段与表中的列名/类型匹配,则可以对所有信息进行参数化和泛化。
因此,如果您有一个包含Person
列和Name varchar(wutev)
列的表Age INTEGER
,则应创建此类:
public class Person
{
public string Name {get; set;}
public int Age {get; set;}
}
然后你的SQL类看起来像这样:
public class MyPersonalORM
{
private string _connectionString;
public MyPersonalORM(string connectionString)
{
_connectionString = connectionString;
}
public T Insert<T>(T insertPlz)
{
string tableName = typeof(T).Name;
Dictionary<string, string> parameters = ...; // Use reflection to get the properties of T, then reflect into insertPlz to find the values.
SqlParameter ... // Add each value in the dictionary to a parameter collection.
// Do a typical Insert, but using Parameters.
}
public T Select<T>(T classForClauses)
{
string tableName = typeof(T).Name;
Dictionary<string, string> parameters = ...; // Use reflection to get the properties of T, then reflect into insertPlz to find the values.
SqlParameter ... // Add each value in the dictionary to a parameter collection.
// Do a typical ADO Selct, but using Parameters for the clauses.
}
}
您可以轻松获得反射。由ORM的使用者来创建映射到数据库类型的类。
为什么呢?因为E.F.是怎么做的。它永远不会询问数据库它是什么类型。 E.F.要求您使用C#类型正确映射资源。
当然,真正的答案是:不要使用ADO。使用E.F.:)