using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Reflection;
namespace MJTop.Data
{
public partial class DBExtend
{
#region 将集合实体转为DataTable
///
/// 将集合实体转为DataTable
///
/// 实体类型
/// 集合
///
public static DataTable EntityToDataTable(IEnumerable lstEntity)
where T:class,new()
{
return EntityToDataTable(lstEntity, null);
}
///
/// 将集合实体转为DataTable
///
/// 实体类型
/// 集合
/// DataTable表名
///
public static DataTable EntityToDataTable(IEnumerable lstEntity, string tableName)
where T : class, new()
{
DataTable data = new DataTable();
Type ty = typeof(T);
if (!string.IsNullOrWhiteSpace(tableName))
{
data.TableName = tableName;
}
else
{
data.TableName = ty.Name;
}
var props = ty.GetProperties();
foreach (var prop in props)
{
data.Columns.Add(prop.Name, prop.PropertyType);
}
foreach (var entity in lstEntity)
{
DataRow dr = data.NewRow();
foreach (DataColumn dc in data.Columns)
{
var prop = ty.GetProperty(dc.ColumnName);
var value = prop.GetValue(entity, null);
dr[dc.ColumnName] = value;
}
data.Rows.Add(dr);
}
return data;
}
#endregion
#region DataTable =》 GetCreateSqlScript
///
/// 根据DataTable获取创建Sql语句
///
/// DataTable
/// 表名
/// 数据库类型
/// 创建表的Sql脚本
public static string GetCreateSqlScript(DataTable data, string tableName, DBType DBType = DBType.SqlServer)
{
if (data == null)
{
throw new ArgumentException("数据表不能为null!", "data");
}
data.TableName = tableName;
return GetCreateSqlScript(data, DBType);
}
///
/// 根据集合实体得到 Sql创建表脚本
///
/// 实体类型
/// 集合
/// 表名
/// 数据库类型
///
public static string GetCreateSqlScript(IEnumerable lstEntity, string tableName, DBType DBType = DBType.SqlServer)
where T : class, new()
{
DataTable data = EntityToDataTable(lstEntity, tableName);
return GetCreateSqlScript(data, DBType);
}
#region private
///
/// 获取列的值的最大小数点占用位数
///
/// DataTable
///
private static Dictionary GetColDecimals(DataTable data)
{
Dictionary dictDecimals = new Dictionary();
List lstTy = new List()
{
typeof(double),
typeof(decimal),
typeof(float)
};
var rowColl = data.AsEnumerable();
var lstCol = data.Columns.ToArray().Where(t => lstTy.Contains(t.DataType));//获取小数类型的列
foreach (DataColumn dc in lstCol)
{
long lngTemp;
var currArr = rowColl.Select(t => t[dc.ColumnName].ToString()); //得到当前列的 ToString()
currArr = currArr.Where(t => t.Length > 0 && !long.TryParse(t, out lngTemp));//不是空字符串,并且Parse失败则才算是真正的小数,过滤 小数点后都是0的数值
if (currArr.Any())
{
var currArrInt = currArr.Select(t => (Regex.Replace(t, @"(\d+)\.(\d+)", "$2", RegexOptions.Compiled)).Length);
int decimals = currArrInt.Max();
dictDecimals[dc.ColumnName] = decimals;
}
}
return dictDecimals;
}
///
/// 根据DataTable获取创建Sql语句
///
/// DataTable
/// 数据库类型
/// 创建表的Sql脚本
private static string GetCreateSqlScript(DataTable data, DBType DBType = DBType.SqlServer)
{
if (data == null)
{
throw new ArgumentException("数据表不能为null!", "data");
}
if (string.IsNullOrWhiteSpace(data.TableName))
{
throw new ArgumentException("表名不能为空!");
}
return GetCreateSqlScript(data, data.Columns, DBType);
}
///
/// 根据 表名,DataColumn[]获取创建Sql语句
///
/// 表名
/// 所有列
/// 数据库类型
/// 创建表的Sql脚本
private static string GetCreateSqlScript(DataTable data, DataColumnCollection dcs, DBType DBType = DBType.SqlServer)
{
//获取主键
DataColumn[] primaryKey = data.PrimaryKey;
if (dcs == null)
{
throw new ArgumentException("列集合不能为null!");
}
if (dcs.Count <= 0)
{
throw new ArgumentException("列集合个数必须大于0!");
}
Dictionary dictDecimals = GetColDecimals(data);
StringBuilder sbSql = new StringBuilder();
sbSql.AppendFormat("create table {0}", data.TableName);
sbSql.Append("(");
for (int j = 0; j < dcs.Count; j++)
{
var dc = dcs[j];
string colSqlType = GetColSqlType(dc, DBType, dictDecimals);
if (dc.AutoIncrement) //是自增列
{
colSqlType += " identity(" + dc.AutoIncrementSeed + "," + dc.AutoIncrementStep + ") ";
}
if (primaryKey.Contains(dc))
{
colSqlType += " primary key ";
}
colSqlType = colSqlType + ((j != dcs.Count - 1) ? "," : "");
sbSql.Append(colSqlType);
}
sbSql.Append(")");
string sql = sbSql.ToString();
return sql;
}
///
/// 返回Sql列类型
///
/// 列
/// 数据库类型
/// 列的值的最大小数点占用位数
/// Sql列类型
private static string GetColSqlType(DataColumn dc, DBType DBType, Dictionary dictDecimals)
{
string res = string.Empty;
string columnName = dc.ColumnName;
Type typecol = Nullable.GetUnderlyingType(dc.DataType) ?? dc.DataType;
switch (typecol.FullName)
{
case "System.Guid":
if (DBType == DBType.SqlServer)
{
res = columnName + " uniqueidentifier";
}
else
{
res = columnName + " char(36)";
}
break;
case "System.Boolean":
if (DBType == DBType.SqlServer || DBType == DBType.MySql)
{
res = columnName + " bit";
}
else if (DBType == DBType.OracleDDTek || DBType == DBType.Oracle)
{
res = columnName + " number(1,0)";
}
else if (DBType == DBType.SQLite)
{
res = columnName + " integer";
}
break;
case "System.Int32":
case "System.Int64":
if (DBType == DBType.SqlServer || DBType == DBType.MySql)
{
res = columnName + " bigint";
}
else if (DBType == DBType.OracleDDTek || DBType == DBType.Oracle)
{
res = columnName + " number(38,0)";
}
else if (DBType == DBType.SQLite)
{
res = columnName + " integer";
}
break;
case "System.Decimal":
case "System.Double":
case "System.Single":
if (DBType == DBType.SqlServer || DBType == DBType.MySql)
{
if (dictDecimals != null && dictDecimals.ContainsKey(dc.ColumnName))
{
res = columnName + " decimal(38," + dictDecimals[dc.ColumnName] + ")";
}
else
{
res = columnName + " bigint";
}
}
else if (DBType == DBType.OracleDDTek || DBType == DBType.Oracle)
{
if (dictDecimals != null && dictDecimals.ContainsKey(dc.ColumnName))
{
res = columnName + " number(38," + dictDecimals[dc.ColumnName] + ")";
}
else
{
res = columnName + " number(38,0)";
}
}
else if (DBType == DBType.SQLite)
{
if (dictDecimals != null && dictDecimals.ContainsKey(dc.ColumnName))
{
res = columnName + " real(38," + dictDecimals[dc.ColumnName] + ")";
}
else
{
res = columnName + " integer";
}
}
break;
case "System.DateTime":
if (DBType == DBType.SqlServer || DBType == DBType.MySql || DBType == DBType.SQLite)
{
res = columnName + " datetime";
}
else if (DBType == DBType.OracleDDTek || DBType == DBType.Oracle)
{
res = columnName + " date";
}
break;
case "System.Byte[]":
//先把数据存进去,使用max
if (DBType == DBType.SqlServer)
{
res = columnName + " varbinary(max)";
}
else if (DBType == DBType.MySql || DBType == DBType.SQLite)
{
res = columnName + " blob";
}
break;
default:
//先把数据存进去,使用max
if (DBType == DBType.SqlServer)
{
res = columnName + " nvarchar(max)";
}
else if (DBType == DBType.MySql || DBType == DBType.SQLite)
{
res = columnName + " text";
}
else if (DBType == DBType.OracleDDTek || DBType == DBType.Oracle)
{
res = columnName + " nclob";
}
break;
}
return res;
}
#endregion
#endregion
#region 反射对象类型的属性生成创建脚本
public static string GetCreateSqlScript(Type ty, DBType DBType = DBType.SqlServer)
{
var props = ty.GetProperties();
StringBuilder sbSql = new StringBuilder();
sbSql.AppendFormat("create table {0}", ty.Name);
sbSql.Append("(");
for (int j = 0; j < props.Length; j++)
{
PropertyInfo pInfo = props[j];
string colType = GetColTypeByProperty(pInfo, DBType);
sbSql.Append(colType + " " + ((j == props.Length - 1) ? "" : ","));
}
sbSql.Append(")");
return sbSql.ToString();
}
private static string GetColTypeByProperty(PropertyInfo pInfo, DBType DBType)
{
string res = string.Empty;
string columnName = pInfo.Name;
Type typecol = Nullable.GetUnderlyingType(pInfo.PropertyType) ?? pInfo.PropertyType;
switch (typecol.FullName)
{
case "System.Guid":
if (DBType == DBType.SqlServer)
{
res = columnName + " uniqueidentifier";
}
else
{
res = columnName + " char(36)";
}
break;
case "System.Boolean":
if (DBType == DBType.SqlServer || DBType == DBType.MySql)
{
res = columnName + " bit";
}
else if (DBType == DBType.OracleDDTek || DBType == DBType.Oracle)
{
res = columnName + " number(1,0)";
}
else if (DBType == DBType.SQLite)
{
res = columnName + " integer";
}
break;
case "System.Int32":
case "System.Int64":
if (DBType == DBType.SqlServer || DBType == DBType.MySql)
{
res = columnName + " bigint";
}
else if (DBType == DBType.OracleDDTek || DBType == DBType.Oracle)
{
res = columnName + " number(38,0)";
}
else if (DBType == DBType.SQLite)
{
res = columnName + " integer";
}
break;
case "System.Decimal":
case "System.Double":
case "System.Single":
if (DBType == DBType.SqlServer || DBType == DBType.MySql)
{
res = columnName + " decimal(38," + 2 + ")";
}
else if (DBType == DBType.OracleDDTek || DBType == DBType.Oracle)
{
res = columnName + " number(38,," + 2 + ")";
}
else if (DBType == DBType.SQLite)
{
res = columnName + " real(38," + 2 + ")";
}
break;
case "System.DateTime":
if (DBType == DBType.SqlServer || DBType == DBType.MySql || DBType == DBType.SQLite)
{
res = columnName + " datetime";
}
else if (DBType == DBType.OracleDDTek || DBType == DBType.Oracle)
{
res = columnName + " date";
}
break;
case "System.Byte[]":
//先把数据存进去,使用max
if (DBType == DBType.SqlServer)
{
res = columnName + " varbinary(max)";
}
else if (DBType == DBType.MySql || DBType == DBType.SQLite)
{
res = columnName + " blob";
}
break;
default:
//先把数据存进去,使用max
if (DBType == DBType.SqlServer)
{
res = columnName + " nvarchar(max)";
}
else if (DBType == DBType.MySql || DBType == DBType.SQLite)
{
res = columnName + " text";
}
else if (DBType == DBType.OracleDDTek || DBType == DBType.Oracle)
{
res = columnName + " nclob";
}
break;
}
return res;
}
#endregion
}
}