I’m trying to create a class to represent the value of a column in SQL. Here’s the final goal I want to reach:
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");
}
So the class is the ColumnValue class mentioned above. The ColumnValue class needs a Value property which can presumably be any basic .NET type (int, string etc). The class also has a property, SqlValue, which provides a string representation of the Value property which I can use in the generated SQL statement. So if Value is an int, then SqlValue just gives Value.ToString(), whereas if Value is a string, SqlValue needs to check if the string is null in order to either return ‘NULL’ or the Value property itself.
Initially I tried to have Value as an object and SqlValue to test the type of Value in a switch statement:
public string SqlValue
{
get
{
switch (Value.GetType())
{
...
}
}
}
But then I get ‘Value of integral type expected’. So I can’t check an object’s type.
Next I tried generics. I changed the ColumnValue class to ColumnValue<T>, with the Value property as follows:
public T Value { get; set; }
And then, in the SqlValue property, another check of the type of T, but I’m not allowed to do that either.
Is there a way to achieve this in C# without simply creating separate classes to handle each possible type of column?
switch keyword can take only integers (correctly speaking, integral type (see here)). But you can always use “if” statements. For example,
You can also use “is” keyword. For example,
“is” operator will also check within inheritance hierarchy but I don’t think that will be the case in your usage.
Lastly, I hope that whatever SqlValue implementation that you are going to do will handle escaping (for example – quotes within string values) and will protect against sql injection attacks. You may consider generating parameterized query insetad (i.e. add parameter for each column in the query and then pass actual values as parameter values – so you won’t need SqlValue property at all).