最近在使用CodeSmith生成MySql数据库的代码时发现了一个问题,就是生成的代码无法获取到字段表的注释和字段的注释,这多不方便了,于是就在网上找解决方案。
搜索之后发现因为mysql的驱动dll少了获取说明的代码,还需要修改CodeSmith相关的代码。
先找到CodeSmith\v7.0\Samples这个文件夹,里边有两个压缩包,把Samples解压,然后打开文件夹,找到Projects\CSharp\MySQLSchemaProvider文件夹,直接把项目添加到vs上进行修改,项目需要用到两个dll,可以在CodeSmith的bin文件夹和AddIns文件夹下找到。修改完成后生成dll,找到CodeSmith\v7.0\SchemaProviders文件夹,把刚刚生成的SchemaExplorer.MySQLSchemaProvider.dll进行覆盖,重试,管用。
下边放上修改后的最终代码。
/// <summary>
/// Gets the extended properties for a given schema object.
/// </summary>
/// <param name="connectionString">The connection string used to connect to the target database.</param>
/// <param name="schemaObject"></param>
/// <returns></returns>
public ExtendedProperty[] GetExtendedProperties(string connectionString, SchemaObjectBase schemaObject)
{
List<ExtendedProperty> extendedProperties = new List<ExtendedProperty>();
if (schemaObject is ColumnSchema)
{
ColumnSchema columnSchema = schemaObject as ColumnSchema;
string commandText = string.Format(@"SELECT EXTRA, COLUMN_DEFAULT, COLUMN_TYPE, COLUMN_COMMENT
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = '{0}' AND TABLE_NAME = '{1}' AND COLUMN_NAME = '{2}'",
columnSchema.Table.Database.Name, columnSchema.Table.Name, columnSchema.Name);
using (DbConnection connection = CreateConnection(connectionString))
{
connection.Open();
DbCommand command = connection.CreateCommand();
command.CommandText = commandText;
command.Connection = connection;
using (IDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection))
{
while (reader.Read())
{
string extra = reader.GetString(0).ToLower();
bool columndefaultisnull = reader.IsDBNull(1);
string columndefault = "";
if (!columndefaultisnull)
{
columndefault = reader.GetString(1).ToUpper();
}
string columntype = reader.GetString(2).ToUpper();
string columncomment = reader.GetString(3);
bool isIdentity = (extra.IndexOf("auto_increment") > -1);
extendedProperties.Add(new ExtendedProperty(ExtendedPropertyNames.IsIdentity, isIdentity, columnSchema.DataType));
if (isIdentity)
{
/*
MySQL auto_increment doesn't work exactly like SQL Server's IDENTITY
I believe that auto_increment is equivalent to IDENTITY(1, 1)
However, auto_increment behaves differently from IDENTITY when used
with multi-column primary keys. See the MySQL Reference Manual for details.
*/
extendedProperties.Add(new ExtendedProperty(ExtendedPropertyNames.IdentitySeed, 1, columnSchema.DataType));
extendedProperties.Add(new ExtendedProperty(ExtendedPropertyNames.IdentityIncrement, 1, columnSchema.DataType));
}
extendedProperties.Add(new ExtendedProperty("CS_ColumnDefaultIsNull", columndefaultisnull, DbType.Boolean)); // Added for Backwards Compatibility.
extendedProperties.Add(new ExtendedProperty(ExtendedPropertyNames.DefaultValue, columndefault, DbType.String));
extendedProperties.Add(new ExtendedProperty("CS_ColumnDefault", columndefault, DbType.String)); // Added for Backwards Compatibility.
extendedProperties.Add(new ExtendedProperty(ExtendedPropertyNames.SystemType, columntype, DbType.String));
extendedProperties.Add(new ExtendedProperty("CS_ColumnType", columntype, DbType.String)); // Added for Backwards Compatibility.
extendedProperties.Add(new ExtendedProperty("CS_ColumnExtra", extra.ToUpper(), DbType.String));
extendedProperties.Add(new ExtendedProperty("CS_Description", columncomment, DbType.String));
}
if (!reader.IsClosed)
reader.Close();
}
if (connection.State != ConnectionState.Closed)
connection.Close();
}
}
if (schemaObject is TableSchema)
{
TableSchema tableSchema = schemaObject as TableSchema;
string commandText = string.Format(@"SHOW CREATE TABLE `{0}`.`{1}`", tableSchema.Database.Name, tableSchema.Name);
using (DbConnection connection = CreateConnection(connectionString))
{
connection.Open();
DbCommand command = connection.CreateCommand();
command.CommandText = commandText;
command.Connection = connection;
using (IDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection))
{
while (reader.Read())
{
string createtable = reader.GetString(1);
extendedProperties.Add(new ExtendedProperty("TS_Description", createtable, DbType.String));
int engineIndex = createtable.LastIndexOf("ENGINE");
int commentIndex = createtable.LastIndexOf("COMMENT=");
string tableDescription = reader.GetString(0);
if (commentIndex > engineIndex)
{
tableDescription = createtable.Substring(commentIndex + 9).Replace("'", "");
}
extendedProperties.Add(new ExtendedProperty("CS_Description", tableDescription, DbType.String));
}
if (!reader.IsClosed)
reader.Close();
}
if (connection.State != ConnectionState.Closed)
connection.Close();
}
}
return extendedProperties.ToArray();
}