我正在尝试创建一个类来表示SQL中列的值。这是我想达到的最终目标:
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
,它提供了Value
属性的字符串表示形式,我可以在生成的SQL语句中使用该属性。因此,如果Value
是一个int,那么SqlValue
只给出Value.ToString()
,而如果Value
是一个字符串,SqlValue
需要检查字符串是否为空命令返回'NULL'或Value
属性本身。
最初我尝试将Value
作为对象,SqlValue
在switch语句中测试Value
的类型:
public string SqlValue
{
get
{
switch (Value.GetType())
{
...
}
}
}
然后我得到'预期的积分类型的价值'。所以我无法检查对象的类型。
接下来我尝试了泛型。我使用ColumnValue
属性将ColumnValue<T>
类更改为Value
,如下所示:
public T Value { get; set; }
然后,在SqlValue
属性中,再次检查T的类型,但我也不允许这样做。
有没有办法在C#中实现这一点,而不是简单地创建单独的类来处理每种可能的列类型?
答案 0 :(得分:0)
switch关键字只能采用整数(正确地说,整数类型(参见here))。但是你总是可以使用“if”语句。例如,
var t = value.GetType();
if (t == typeof(string))
{
..
}
else if (t == typeof(int))
{
}
else if ...
您还可以使用“是”关键字。例如,
if (value is string)
{
...
}
else if (value is int)
{
...
}
else if ...
“是”运算符也将在继承层次结构中进行检查,但我不认为您的使用情况会如此。
最后,我希望您要执行的任何SqlValue实现都将处理转义(例如 - 字符串值中的引号)并防止sql注入攻击。您可以考虑生成参数化查询insetad(即为查询中的每一列添加参数,然后将实际值作为参数值传递 - 因此您根本不需要SqlValue属性。)
答案 1 :(得分:0)
如果使用参数,则可以让SqlValue返回一个对象。
您的示例需要在字符串周围添加引号并处理文化问题(格式化double,date)。
答案 2 :(得分:0)
您还可以使用Type.GetTypeCode(Value.GetType()),它将把它变成枚举TypeCode,它具有从数据库中检索的所有原始值,尤其是枚举。除了作为对象出现的Guid之外,你可以在对象块中处理它。