2010-10-11 36 views
0

我试图创建一个类来表示SQL中列的值。下面是最终目标,我想达到:如何在C中创建包含各种类型属性的类#

public string GenerateInsertSql() 
{ 
    StringBuilder insertSql = new StringBuilder(); 
    insertSql.Append("INSERT INTO " + SchemaName + "." + TableName + "\n"); 
    insertSql.Append("(\n"); 
    int counter = 0; 
    foreach (ColumnValue columnValue in _insertValues) 
    { 
    if (counter > 0) insertSql.Append(","); 
    counter++; 
    insertSql.Append(columnValue.ColumnName).Append("\n"); 
    } 
    insertSql.Append(")\n"); 
    insertSql.Append("VALUES\n"); 
    insertSql.Append("(\n"); 
    counter = 0; 
    foreach (ColumnValue columnValue in _insertValues) 
    { 
    if (counter > 0) insertSql.Append(","); 
    counter++; 
    insertSql.Append(columnValue.SqlValue).Append("\n"); 
    } 
    insertSql.Append(")\n"); 
} 

因此类是上面提到的ColumnValue类。 ColumnValue类需要一个Value属性,它可能是任何基本的.NET类型(int,string等)。该类还有一个属性SqlValue,它提供了可在生成的SQL语句中使用的Value属性的字符串表示形式。所以如果Value是一个int,那么SqlValue只是给出Value.ToString(),而如果Value是一个字符串,SqlValue需要检查字符串是否为空以便返回'NULL'或Value属性本身。

起初我想有Value为对象,以及SqlValue测试的Value类型switch语句:

public string SqlValue 
{ 
    get 
    { 
    switch (Value.GetType()) 
    { 
     ... 
    } 
    } 
} 

但后来我得到“整型预期价值”。所以我无法检查一个对象的类型。

接下来我尝试了泛型。我改变了ColumnValueColumnValue<T>,与Value属性,如下所示:

public T Value { get; set; } 

,然后在SqlValue财产,T类型的另一种检验,但我不允许这样做,要么。

有没有办法在C#中实现这一点,而无需简单地创建单独的类来处理每种可能的列类型?

+0

通过字符串连接创建SQL?我会更担心Sql注入。 – spender 2010-10-11 10:01:49

+0

感谢您的警告,但这只是测试类的SQL生成。没有涉及任何用户输入。 – David 2010-10-11 10:08:25

+0

还值得指出的是,上面的SQL可以快速修改为参数化值,从而完全保护它。 – David 2010-10-11 10:09:17

回答

0

switch关键字只能取整数(正确地说,整数类型(见here))。但是你总是可以使用“if”语句。例如,

var t = value.GetType(); 
if (t == typeof(string)) 
{ 
    .. 
} 
else if (t == typeof(int)) 
{ 
} 
else if ... 

您还可以使用“is”关键字。例如,

if (value is string) 
{ 
    ... 
} 
else if (value is int) 
{ 
    ... 
} 
else if ... 

“is”操作符也会在继承层次结构中进行检查,但我认为您的使用情况不会这样。

最后,我希望无论您将要做的SqlValue实现如何处理转义(例如 - 字符串值中的引号)并防止SQL注入攻击。您可以考虑生成参数化查询insetad(即为查询中的每个列添加参数,然后将实际值作为参数值传递 - 因此根本不需要SqlValue属性)。

+4

开关只接收整数是不正确的。可能最好编辑一个。 – David 2010-10-11 10:07:19

+0

关于你的最后一段,它是这里需要的可空类型的空检查 - 这是SqlValue属性的目的。 – David 2010-10-11 10:11:21

+0

@大卫,谢谢你指出 - 现在纠正。 – VinayC 2010-10-11 10:16:13

0

如果你使用参数,你可以让你的SqlValue只返回一个对象。

您的示例需要在字符串周围添加引号并处理文化问题(格式化为double,date)。

+0

而且还测试null ...你是正确的报价和日期格式。 – David 2010-10-11 10:26:14

0

你也可以使用Type.GetTypeCode(Value.GetType()),它将把它变成枚举TypeCode,它具有从数据库中检索的所有原始值,特别是枚举。除了Guid会作为对象出现,但你可以在对象块中处理它。

+0

有用。谢谢。 – David 2010-10-11 13:38:21

相关问题