I encoded a reasonable solution, but was hoping to avoid case statements for SQL types:
First, a neat trick to convert from a .NET type to SqlDBType:
public static SqlDbType GetSqlDBTypeFromType(Type type)
{
TypeConverter tc = TypeDescriptor.GetConverter(typeof(DbType));
if ( true)
{
DbType dbType = (DbType)tc.ConvertFrom(type.Name);
SqlParameter param = new SqlParameter();
param.DbType = dbType;
return param.SqlDbType;
}
else
{
throw new Exception("Cannot get SqlDbType from: " + type.Name);
}
}
Case statement for types for use in SQL statements:
public static string GetSqlServerCETypeName(SqlDbType dbType, int size)
{
bool max = (size == int.MaxValue) ? true : false;
bool over4k = (size > 4000) ? true : false;
switch (dbType)
{
case SqlDbType.BigInt:
return "bigint";
case SqlDbType.Binary:
return string.Format("binary ({0})", size);
case SqlDbType.Bit:
return "bit";
case SqlDbType.Char:
if (over4k) return "ntext";
else return string.Format("nchar({0})", size);
ETC...
Then, finally, the CREATE TABLE statement:
public static string GetCreateTableStatement(string tableName, DataTable schema)
{
StringBuilder builder = new StringBuilder();
builder.Append(string.Format("CREATE TABLE [{0}] (\n", tableName));
foreach (DataRow row in schema.Rows)
{
string typeName = row["DataType"].ToString();
Type type = Type.GetType(typeName);
string name = (string)row["ColumnName"];
int size = (int)row["ColumnSize"];
SqlDbType dbType = GetSqlDBTypeFromType(type);
builder.Append(name);
builder.Append(" ");
builder.Append(GetSqlServerCETypeName(dbType, size));
builder.Append(", ");
}
if (schema.Rows.Count > 0) builder.Length = builder.Length - 2;
builder.Append("\n)");
return builder.ToString();
}
source
share