実行時にDataTable
のスキーマに基づいてSQL Server CE(Compact 3.5)テーブルを作成する最良の方法を知っている人はいますか?私はCREATE TABLE
ステートメントを可能なすべてのデータ型に基づいて定式化する必要はありません。DataTableからSQL Server CEテーブルをプログラムで作成する
これは、データテーブルから直接入力する方法を知っていますか?
実行時にDataTable
のスキーマに基づいてSQL Server CE(Compact 3.5)テーブルを作成する最良の方法を知っている人はいますか?私はCREATE TABLE
ステートメントを可能なすべてのデータ型に基づいて定式化する必要はありません。DataTableからSQL Server CEテーブルをプログラムで作成する
これは、データテーブルから直接入力する方法を知っていますか?
私は合理的な解決策をコード化されますが、SQLの種類のcase文を避けるために期待していた。第一
なSQLDbTypeに.NET型から変換するために巧妙なトリック:
/// <summary>
/// Gets the correct SqlDBType for a given .NET type. Useful for working with SQL CE.
/// </summary>
/// <param name="type">The .Net Type used to find the SqlDBType.</param>
/// <returns>The correct SqlDbType for the .Net type passed in.</returns>
public static SqlDbType GetSqlDBTypeFromType(Type type)
{
TypeConverter tc = TypeDescriptor.GetConverter(typeof(DbType));
if (/*tc.CanConvertFrom(type)*/ true)
{
DbType dbType = (DbType)tc.ConvertFrom(type.Name);
// A cheat, but the parameter class knows how to map between DbType and SqlDBType.
SqlParameter param = new SqlParameter();
param.DbType = dbType;
return param.SqlDbType; // The parameter class did the conversion for us!!
}
else
{
throw new Exception("Cannot get SqlDbType from: " + type.Name);
}
}
場合SQL文で使用するタイプのための声明:次に
/// <summary>
/// The method gets the SQL CE type name for use in SQL Statements such as CREATE TABLE
/// </summary>
/// <param name="dbType">The SqlDbType to get the type name for</param>
/// <param name="size">The size where applicable e.g. to create a nchar(n) type where n is the size passed in.</param>
/// <returns>The SQL CE compatible type for use in SQL Statements</returns>
public static string GetSqlServerCETypeName(SqlDbType dbType, int size)
{
// Conversions according to: http://msdn.microsoft.com/en-us/library/ms173018.aspx
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...
最後に、CREATE TABLEステートメント:
/// <summary>
/// Genenerates a SQL CE compatible CREATE TABLE statement based on a schema obtained from
/// a SqlDataReader or a SqlCeDataReader.
/// </summary>
/// <param name="tableName">The name of the table to be created.</param>
/// <param name="schema">The schema returned from reader.GetSchemaTable().</param>
/// <returns>The CREATE TABLE... Statement for the given schema.</returns>
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();
}
私はベンブリーンから使用してコードを更新しました:すべてのタイプ
GetSqlDBTypeFromType
/// <summary>
/// Gets the correct SqlDBType for a given .NET type. Useful for working with SQL CE.
/// </summary>
/// <param name="type">The .Net Type used to find the SqlDBType.</param>
/// <returns>The correct SqlDbType for the .Net type passed in.</returns>
public static SqlDbType GetSqlDBTypeFromType(Type type)
{
TypeConverter tc = TypeDescriptor.GetConverter(typeof(DbType));
if (/*tc.CanConvertFrom(type)*/ true)
{
DbType dbType = (DbType)tc.ConvertFrom(type.Name);
// A cheat, but the parameter class knows how to map between DbType and SqlDBType.
SqlCeParameter param = new SqlCeParameter();
param.DbType = dbType;
return param.SqlDbType; // The parameter class did the conversion for us!!
}
else
{
throw new Exception("Cannot get SqlDbType from: " + type.Name);
}
}
GetSqlServerCETypeName
/// <summary>
/// The method gets the SQL CE type name for use in SQL Statements such as CREATE TABLE
/// </summary>
/// <param name="dbType">The SqlDbType to get the type name for</param>
/// <param name="size">The size where applicable e.g. to create a nchar(n) type where n is the size passed in.</param>
/// <returns>The SQL CE compatible type for use in SQL Statements</returns>
public static string GetSqlServerCETypeName(SqlDbType dbType, int size)
{
// Conversions according to: http://msdn.microsoft.com/en-us/library/ms173018.aspx
bool max = (size == int.MaxValue) ? true : false;
bool over4k = (size > 4000) ? true : false;
if (size>0)
{
return string.Format(Enum.GetName(typeof(SqlDbType), dbType)+" ({0})", size);
}
else
{
return Enum.GetName(typeof(SqlDbType), dbType);
}
}
GetCreateTableStatement
/// <summary>
/// Genenerates a SQL CE compatible CREATE TABLE statement based on a schema obtained from
/// a SqlDataReader or a SqlCeDataReader.
/// </summary>
/// <param name="tableName">The name of the table to be created.</param>
/// <param name="schema">The schema returned from reader.GetSchemaTable().</param>
/// <returns>The CREATE TABLE... Statement for the given schema.</returns>
public static string GetCreateTableStatement(DataTable table)
{
StringBuilder builder = new StringBuilder();
builder.Append(string.Format("CREATE TABLE [{0}] (", table.TableName));
foreach (DataColumn col in table.Columns)
{
SqlDbType dbType = GetSqlDBTypeFromType(col.DataType);
builder.Append("[");
builder.Append(col.ColumnName);
builder.Append("]");
builder.Append(" ");
builder.Append(GetSqlServerCETypeName(dbType, col.MaxLength));
builder.Append(", ");
}
if (table.Columns.Count > 0) builder.Length = builder.Length - 2;
builder.Append(")");
return builder.ToString();
}
CreateFromDataset
public static void CreateFromDataset(DataSet set, SqlCeConnection conn)
{
conn.Open();
SqlCeCommand cmd;
foreach (DataTable table in set.Tables)
{
string createSql = copyDB.GetCreateTableStatement(table);
Console.WriteLine(createSql);
cmd = new SqlCeCommand(createSql, conn);
Console.WriteLine(cmd.ExecuteNonQuery());
}
conn.Close();
}
}
ナイス!しかし、空のDataTableまたは複数の行がある場合、正しく動作しません。私は "DataRow-foreach" -loopをschema.Columnsのループに置き換え、各列のColumnName-とMaxLength-プロパティを使用しました。 – Lars
また、ID列の設定などがないテーブルも作成しています.FillSchemaの呼び出しですべて利用できるので、動的にビルドすることができます。 –