根据DbSchema生成代码
public interface IDbSchema { IDbTableSchema[] GetSchema(); } public interface IDbTableSchema { string Name { get; } IDbColumnSchema[] Columns { get; } } public interface IDbColumnSchema { int Ordinal { get; } string Name { get; } bool IsNullable { get; } bool IsPrimaryKey { get; } Type FieldType { get; } }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.OleDb;
using Rocky.Data;
namespace Rocky.CodeBuilder
{
public class DbSchema : IDbSchema
{
#region Properties
protected DbFactory factory;
public DbFactory Factory { get { return factory; } }
#endregion
#region Methods
public DbSchema(DbFactory factory)
{
this.factory = factory;
}
#region old
[Obsolete("Old", true)]
public DataSet GetSchema(string Comments)
{
var connstr = "Provider=SQLOLEDB;" + factory.ConnectionString;
DataSet ds = new DataSet();
using (OleDbConnection conn = new OleDbConnection(connstr))
using (OleDbDataAdapter da = new OleDbDataAdapter(conn.CreateCommand()))
{
conn.Open();
DataTable tables = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
conn.Close();
for (int i = 0; i < tables.Rows.Count; i++)
{
string sql = "SELECT * FROM [" + tables.Rows[i]["TABLE_NAME"].ToString() + "] WHERE 1=-1";
da.SelectCommand.CommandText = sql;
DataTable dt = new DataTable(tables.Rows[i]["TABLE_NAME"].ToString());
//自定义属性 ClassName ClassComments
dt.ExtendedProperties["ClassName"] = dt.TableName + "Entity";
dt.ExtendedProperties["Comments"] = Comments;
dt.ExtendedProperties["IsSaveToMemory"] = false;
da.FillSchema(dt, SchemaType.Source);
ds.Tables.Add(dt);
//标识主键
DataColumn[] columns = dt.PrimaryKey;
for (int j = 0; j < columns.Length; j++)
{
columns[j].ExtendedProperties.Add("Key", "primary");
}
}
}
return ds;
}
#endregion
public virtual DbTableSchema[] GetSchema()
{
var conn = factory.CreateConnection();
conn.Open();
DataTable dt = conn.GetSchema("tables");
DataTable dc = conn.GetSchema("columns");
conn.Close();
List tables = new List();
Database db = new Database(factory);
dt.DefaultView.Sort = "TABLE_NAME ASC";
foreach (DataRowView tRow in dt.DefaultView)
{
if (tRow["TABLE_TYPE"].ToString() != "TABLE")
{
continue;
}
DbTableSchema table = new DbTableSchema();
table.Name = tRow["TABLE_NAME"].ToString();
List columns = new List();
using (var dr = db.ExecuteStoredProcReader("SELECT TOP 1 * FROM [" + table.Name + "]"))
{
for (int i = 0; i < dr.FieldCount; i++)
{
DbColumnSchema column = new DbColumnSchema(i);
column.Name = dr.GetName(i);
column.FieldType = dr.GetFieldType(i);
foreach (DataRow cRow in dc.Rows)
{
if (String.Compare(cRow["COLUMN_NAME"].ToString(), column.Name, true) == 0)
{
column.IsNullable = (bool)cRow["IS_NULLABLE"];
}
}
if (i == 0)
{
column.IsPrimaryKey = column.FieldType == typeof(int);
}
columns.Add(column);
}
}
table.Columns = columns.ToArray();
tables.Add(table);
}
return tables.ToArray();
}
#endregion
#region IDbSchema 成员
IDbTableSchema[] IDbSchema.GetSchema()
{
return GetSchema();
}
#endregion
}
#region DbTableSchema
public class DbTableSchema : IDbTableSchema
{
private string name;
protected Array columns;
public string Name
{
get { return name; }
set { name = CoreHelper.ToTitleUpperCase(value); }
}
public DbColumnSchema[] Columns
{
get { return this.DbColumns; }
set { this.DbColumns = value; }
}
protected virtual DbColumnSchema[] DbColumns
{
get { return (DbColumnSchema[])columns; }
set { columns = value ?? new DbColumnSchema[0]; }
}
IDbColumnSchema[] IDbTableSchema.Columns
{
get { return this.Columns; }
}
}
public class DbColumnSchema : IDbColumnSchema
{
private string name, prefixName, lowerName;
public int Ordinal { get; private set; }
public string Name
{
get { return name; }
set
{
name = CoreHelper.ToTitleUpperCase(value);
prefixName = "_" + name;
lowerName = name.ToLower();
}
}
public string PrefixName
{
get { return prefixName; }
}
public string LowerName
{
get { return lowerName; }
}
public bool IsNullable { get; set; }
public bool IsPrimaryKey { get; set; }
public Type FieldType { get; set; }
public DbColumnSchema(int ordinal)
{
this.Ordinal = ordinal;
this.IsNullable = true;
}
}
#endregion
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.IO;
using Rocky.Data;
namespace Rocky.CodeBuilder
{
public class SqlSchema : DbSchema
{
#region SqlToCShap
private static Type SqlToCShap(string sqlType)
{
Type type;
switch (sqlType.ToLower())
{
case "int":
type = typeof(int);
break;
case "bigint":
type = typeof(long);
break;
case "binary":
case "image":
case "varbinary":
type = typeof(byte[]);
break;
case "bit":
type = typeof(bool);
break;
case "char":
case "nchar":
type = typeof(char);
break;
case "datetime":
case "smalldatetime":
case "timestamp":
type = typeof(DateTime);
break;
case "decimal":
case "money":
case "numeric":
case "smallmoney":
type = typeof(decimal);
break;
case "float":
type = typeof(double);
break;
case "real":
type = typeof(float);
break;
case "smallint":
type = typeof(short);
break;
case "tinyint":
type = typeof(byte);
break;
case "uniqueidentifier":
type = typeof(Guid);
break;
case "Variant":
type = typeof(object);
break;
case "varchar":
case "text":
case "nvarchar":
case "ntext":
default:
type = typeof(string);
break;
}
return type;
}
#endregion
#region Fields
#region sqlGetTables
private static string sqlGetTables = @"
SELECT
TableId = O.object_id,
TableName = O.name,
TableDesc = PTB.[value]
FROM sys.columns C
INNER JOIN sys.objects O
ON C.[object_id]=O.[object_id]
AND O.type='U'
AND O.is_ms_shipped=0
INNER JOIN sys.types T
ON C.user_type_id=T.user_type_id
LEFT JOIN sys.extended_properties PTB
ON PTB.class=1
AND PTB.minor_id=0
AND C.[object_id]=PTB.major_id
AND PTB.[name] = 'MS_Description'
WHERE C.column_id=1
ORDER BY TableName
";
#endregion
#region sqlGetColumns
private static string sqlGetColumns = @"
SELECT
TableName = CASE WHEN C.column_id=1 THEN O.name ELSE N'' END,
TableDesc = ISNULL(CASE WHEN C.column_id=1 THEN PTB.[value] END,N''),
Column_id = C.column_id,
ColumnName = C.name,
ColumnDesc = ISNULL(PFD.[value],N''),
[Type] = T.name,
Length = C.max_length,
[Precision] = C.precision,
Scale = C.scale,
Nullable = CASE WHEN C.is_nullable=1 THEN N'√'ELSE N'' END,
[Default] = ISNULL(D.definition,N''),
[IDENTITY] = CASE WHEN C.is_identity=1 THEN N'√'ELSE N'' END,
Computed = CASE WHEN C.is_computed=1 THEN N'√'ELSE N'' END,
PrimaryKey = ISNULL(IDX.PrimaryKey,N''),
IndexName = ISNULL(IDX.IndexName,N''),
IndexSort = ISNULL(IDX.Sort,N''),
Create_Date = O.Create_Date,
Modify_Date = O.Modify_date
FROM sys.columns C
INNER JOIN sys.objects O
ON C.[object_id]=O.[object_id]
AND O.type='U'
AND O.is_ms_shipped=0
INNER JOIN sys.types T
ON C.user_type_id=T.user_type_id
LEFT JOIN sys.default_constraints D
ON C.[object_id]=D.parent_object_id
AND C.column_id=D.parent_column_id
AND C.default_object_id=D.[object_id]
LEFT JOIN sys.extended_properties PFD
ON PFD.class=1
AND C.[object_id]=PFD.major_id
AND C.column_id=PFD.minor_id
AND PFD.name='MS_Description' -- 字段说明对应的描述名称(一个字段可以添加多个不同name的描述)
LEFT JOIN sys.extended_properties PTB
ON PTB.class=1
AND PTB.minor_id=0
AND C.[object_id]=PTB.major_id
AND PTB.name='MS_Description' -- 表说明对应的描述名称(一个表可以添加多个不同name的描述)
LEFT JOIN -- 索引及主键信息
(
SELECT
IDXC.[object_id],
IDXC.column_id,
Sort=CASE INDEXKEY_PROPERTY(IDXC.[object_id],IDXC.index_id,IDXC.index_column_id,'IsDescending')
WHEN 1 THEN 'DESC' WHEN 0 THEN 'ASC' ELSE '' END,
PrimaryKey=CASE WHEN IDX.is_primary_key=1 THEN N'√'ELSE N'' END,
IndexName=IDX.Name
FROM sys.indexes IDX
INNER JOIN sys.index_columns IDXC
ON IDX.[object_id]=IDXC.[object_id]
AND IDX.index_id=IDXC.index_id
LEFT JOIN sys.key_constraints KC
ON IDX.[object_id]=KC.[parent_object_id]
AND IDX.index_id=KC.unique_index_id
INNER JOIN -- 对于一个列包含多个索引的情况,只显示第1个索引信息
(
SELECT [object_id], Column_id, index_id=MIN(index_id)
FROM sys.index_columns
GROUP BY [object_id], Column_id
) IDXCUQ
ON IDXC.[object_id]=IDXCUQ.[object_id]
AND IDXC.Column_id=IDXCUQ.Column_id
AND IDXC.index_id=IDXCUQ.index_id
) IDX
ON C.[object_id]=IDX.[object_id]
AND C.column_id=IDX.column_id
WHERE O.name=N'{0}' -- 如果只查询指定表,加上此条件
ORDER BY O.name,C.column_id
";
#endregion
#endregion
#region Methods
public SqlSchema(DbFactory factory)
: base(factory)
{
}
protected Database GetDatabase()
{
return new Database(this.factory);
}
public override DbTableSchema[] GetSchema()
{
return GetSqlSchema();
//return base.GetSchema();
}
public SqlTableSchema[] GetSqlSchema()
{
var db = GetDatabase();
List tables = new List();
Func func = table =>
{
using (var reader = db.ExecuteStoredProcReader(string.Format(sqlGetColumns, table.Name)))
{
List columns = new List();
while (reader.Read())
{
SqlColumnSchema column = new SqlColumnSchema(columns.Count);
column.ColumnId = Convert.ToInt32(reader["Column_id"]);
column.Name = reader["ColumnName"].ToString();
column.SqlType = reader["Type"].ToString();
column.FieldType = SqlToCShap(column.SqlType);
column.Length = Convert.ToInt32(reader["Length"]);
column.Description = reader["ColumnDesc"].ToString();
column.IsNullable = reader["Nullable"].ToString() == "√";
column.IsIdentity = reader["Identity"].ToString() == "√";
column.IsPrimaryKey = reader["PrimaryKey"].ToString() == "√";
column.IndexName = reader["IndexName"].ToString().Trim();
column.IndexSort = reader["IndexSort"].ToString();
columns.Add(column);
}
return columns.ToArray();
}
};
using (var reader = db.ExecuteStoredProcReader(sqlGetTables))
{
while (reader.Read())
{
SqlTableSchema table = new SqlTableSchema();
table.TableId = Convert.ToInt32(reader["TableId"]);
table.Name = reader["TableName"].ToString();
table.Description = reader["TableDesc"].ToString();
table.Columns = func(table);
tables.Add(table);
}
}
return tables.ToArray();
}
public void Draw(SqlTableSchema[] tables)
{
var conn = factory.CreateConnection();
string database = conn.Database;
for (int i = 0; i < tables.Length; i++)
{
Image.DrawPhoto(database, tables[i], SystemConfig.Instance.SavePath + @"\" + SystemConfig.Instance.FolderName + @"\DbImg\", i + 1);
}
}
#endregion
}
#region SqlTableSchema
public class SqlTableSchema : DbTableSchema
{
public int TableId { get; set; }
public string Description { get; set; }
public new SqlColumnSchema[] Columns
{
get { return (SqlColumnSchema[])base.columns; }
set { base.columns = value ?? new SqlColumnSchema[0]; }
}
protected override DbColumnSchema[] DbColumns
{
get { return this.Columns; }
set { this.Columns = (SqlColumnSchema[])value; }
}
}
public class SqlColumnSchema : DbColumnSchema
{
public int ColumnId { get; set; }
public string SqlType { get; set; }
public int Length { get; set; }
public string Description { get; set; }
public bool IsIdentity { get; set; }
public string IndexName { get; set; }
public string IndexSort { get; set; }
public SqlColumnSchema(int ordinal)
: base(ordinal)
{
}
}
#endregion
#region Image
public static class Image
{
public static void DrawPhoto(string database, SqlTableSchema table, string dir, int counter)
{
string fontFamily = "SimSun";
float fontSize = 1.5F;
int vFontSize = 9;
int imageWidth = 0;
int imageHeight = 0;
int rowHeight = 20;
int borderWidth = 4;
int nameWidth = 0;
int typeWidth = 0;
int descWidth = 0;
Font titleFont = new Font(fontFamily, fontSize, FontStyle.Bold);
Font vTitleFont = new Font(fontFamily, vFontSize, FontStyle.Bold);
string number = string.Format("[{0}]", counter.ToString());
int numberWidth = TextRenderer.MeasureText(number, vTitleFont).Width;
string title = string.Format("{0} ({1})", table.Name, table.Description);
string fullTitle = number + title;
int titleWidth = TextRenderer.MeasureText(fullTitle, vTitleFont).Width;
// 计算图高
imageHeight = rowHeight + rowHeight * table.Columns.Length + borderWidth * 2;
// 计算列宽、图宽
foreach (SqlColumnSchema column in table.Columns)
{
Font font = new Font(fontFamily, vFontSize);
int tmpNameWidth = TextRenderer.MeasureText(column.Name, font).Width + borderWidth;
int tmpTypeWidth = TextRenderer.MeasureText(column.SqlType + "(" + column.Length + ")", font).Width + borderWidth;
int tmpDescWidth = TextRenderer.MeasureText(column.Description, font).Width + borderWidth;
if (tmpNameWidth > nameWidth)
nameWidth = tmpNameWidth;
if (tmpTypeWidth > typeWidth)
typeWidth = tmpTypeWidth;
if (tmpDescWidth > descWidth)
descWidth = tmpDescWidth;
}
imageWidth = nameWidth + typeWidth + descWidth + borderWidth * 2;
// 标题宽度较大
if (titleWidth > imageWidth)
imageWidth = titleWidth;
Bitmap bitmap = new Bitmap(imageWidth, imageHeight);
bitmap.SetResolution(600, 600);
Graphics graphics = Graphics.FromImage(bitmap);
// 填充背景
graphics.FillRectangle(new SolidBrush(Color.White), 0, 0, imageWidth, imageHeight);
// 画竖线
graphics.DrawLine(new Pen(Color.LightGray, 1), new Point(nameWidth, rowHeight + borderWidth), new Point(nameWidth, imageHeight));
graphics.DrawLine(new Pen(Color.LightGray, 1), new Point(nameWidth + typeWidth, rowHeight + borderWidth), new Point(nameWidth + typeWidth, imageHeight));
// 画横线
for (int i = 0; i < table.Columns.Length; i++)
graphics.DrawLine(new Pen(Color.LightGray, 1), new Point(0, rowHeight + borderWidth + rowHeight * i), new Point(imageWidth, rowHeight + borderWidth + rowHeight * i));
// 画外边框
graphics.DrawLine(new Pen(Color.Gray, borderWidth), new Point(0, 0), new Point(imageWidth, 0));
graphics.DrawLine(new Pen(Color.Gray, borderWidth), new Point(0, imageHeight), new Point(imageWidth, imageHeight));
graphics.DrawLine(new Pen(Color.Gray, borderWidth), new Point(0, 0), new Point(0, imageHeight));
graphics.DrawLine(new Pen(Color.Gray, borderWidth), new Point(imageWidth, 0), new Point(imageWidth, imageHeight));
// 画表名
graphics.DrawString(number, titleFont, new SolidBrush(Color.Green), borderWidth, borderWidth);
graphics.DrawString(title, titleFont, new SolidBrush(Color.Black), borderWidth + numberWidth, borderWidth);
// 画字段
for (int i = 0; i < table.Columns.Length; i++)
{
SolidBrush brush = new SolidBrush(Color.Black);
Font font = new Font(fontFamily, fontSize);
// 存在索引就将文字变成蓝色
if (table.Columns[i].IndexName != "")
brush = new SolidBrush(Color.Blue);
// 是标识就将文字加下划线
if (table.Columns[i].IsIdentity)
font = new Font(fontFamily, fontSize, FontStyle.Underline);
// 是主键就将文字颜色改为红色
if (table.Columns[i].IsPrimaryKey)
brush = new SolidBrush(Color.Red);
graphics.DrawString(table.Columns[i].Name, font, brush, borderWidth, rowHeight + borderWidth * 2 + rowHeight * i);
graphics.DrawString(table.Columns[i].SqlType + "(" + table.Columns[i].Length + ")", font, brush, nameWidth + borderWidth, rowHeight + borderWidth * 2 + rowHeight * i);
graphics.DrawString(table.Columns[i].Description, font, brush, nameWidth + typeWidth + borderWidth, rowHeight + borderWidth * 2 + rowHeight * i);
}
string path = string.Format("{0}\\{1}", dir, database);
string fullPath = string.Format("{0}\\{1}.png", path, table.Name);
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
bitmap.Save(fullPath);
}
}
#endregion
}
posted on 2013-04-02 18:45 RockyLOMO 阅读(...) 评论(...) 编辑 收藏