using Ant.Service.Common;
using Central.Control.Domain;
using System;
using System.Collections;
using System.Data;
using System.Data.Entity;
using System.Reflection;
using System.Reflection.Emit;
namespace MES.Production.Service
{
///
/// 查询动态类
/// add 作者: 季健国 QQ:181589805 by 2016-05-10
///
public static class DatabaseExtensions
{
///
/// 自定义Connection对象
///
private static IDbConnection DefaultConnection
{
get
{
return MyConfig.DefaultConnection;
}
}
///
/// 自定义数据库连接字符串,与EF连接模式一致
///
private static string DefaultConnectionString
{
get
{
return MyConfig.DefaultConnectionString;
}
}
///
/// 动态查询主方法
///
///
public static IEnumerable SqlQueryForDynamic(this Database db,
string sql,
params object[] parameters)
{
IDbConnection defaultConn = DefaultConnection;
//ADO.NET数据库连接字符串
db.Connection.ConnectionString = DefaultConnectionString;
return SqlQueryForDynamicOtherDB(db, sql, defaultConn, parameters);
}
private static IEnumerable SqlQueryForDynamicOtherDB(this Database db, string sql, IDbConnection conn, params object[] parameters)
{
conn.ConnectionString = db.Connection.ConnectionString;
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
IDbCommand cmd = conn.CreateCommand();
cmd.CommandText = sql;
if (parameters != null)
{
foreach (var item in parameters)
{
cmd.Parameters.Add(item);
}
}
using (IDataReader dataReader = cmd.ExecuteReader())
{
if (!dataReader.Read())
{
return null; //无结果返回Null
}
#region 构建动态字段
TypeBuilder builder = DatabaseExtensions.CreateTypeBuilder(
"EF_DynamicModelAssembly",
"DynamicModule",
"DynamicType");
int fieldCount = dataReader.FieldCount;
for (int i = 0; i < fieldCount; i++)
{
Type t = dataReader.GetFieldType(i);
switch (t.Name.ToLower())
{
case "decimal":
t = typeof(Decimal?);
break;
case "double":
t = typeof(Double?);
break;
case "datetime":
t = typeof(DateTime?);
break;
case "single":
t = typeof(float?);
break;
case "int16":
t = typeof(int?);
break;
case "int32":
t = typeof(int?);
break;
case "int64":
t = typeof(int?);
break;
default:
break;
}
DatabaseExtensions.CreateAutoImplementedProperty(
builder,
dataReader.GetName(i),
t);
}
#endregion
cmd.Parameters.Clear();
dataReader.Close();
dataReader.Dispose();
cmd.Dispose();
conn.Close();
conn.Dispose();
Type returnType = builder.CreateType();
if (parameters != null)
{
return db.SqlQuery(returnType, sql, parameters);
}
else
{
return db.SqlQuery(returnType, sql);
}
}
}
private static TypeBuilder CreateTypeBuilder(string assemblyName, string moduleName, string typeName)
{
TypeBuilder typeBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(
new AssemblyName(assemblyName),
AssemblyBuilderAccess.Run).DefineDynamicModule(moduleName).DefineType(typeName,
TypeAttributes.Public);
typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);
return typeBuilder;
//TypeBuilder typeBuilder = AppCurrentDefineDynamicAssembly(
// new AssemblyName(assemblyName),
// AssemblyBuilderAccess.Run).DefineDynamicModule(moduleName).DefineType(typeName,
// TypeAttributes.Public);
//typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);
//return typeBuilder;
}
private static void CreateAutoImplementedProperty(TypeBuilder builder, string propertyName, Type propertyType)
{
const string PrivateFieldPrefix = "m_";
const string GetterPrefix = "get_";
const string SetterPrefix = "set_";
// Generate the field.
FieldBuilder fieldBuilder = builder.DefineField(
string.Concat(
PrivateFieldPrefix, propertyName),
propertyType,
FieldAttributes.Private);
// Generate the property
PropertyBuilder propertyBuilder = builder.DefineProperty(
propertyName,
System.Reflection.PropertyAttributes.HasDefault,
propertyType, null);
// Property getter and setter attributes.
MethodAttributes propertyMethodAttributes = MethodAttributes.Public
| MethodAttributes.SpecialName
| MethodAttributes.HideBySig;
// Define the getter method.
MethodBuilder getterMethod = builder.DefineMethod(
string.Concat(
GetterPrefix, propertyName),
propertyMethodAttributes,
propertyType,
Type.EmptyTypes);
// Emit the IL code.
// ldarg.0
// ldfld,_field
// ret
ILGenerator getterILCode = getterMethod.GetILGenerator();
getterILCode.Emit(OpCodes.Ldarg_0);
getterILCode.Emit(OpCodes.Ldfld, fieldBuilder);
getterILCode.Emit(OpCodes.Ret);
// Define the setter method.
MethodBuilder setterMethod = builder.DefineMethod(
string.Concat(SetterPrefix, propertyName),
propertyMethodAttributes,
null,
new Type[] { propertyType });
// Emit the IL code.
// ldarg.0
// ldarg.1
// stfld,_field
// ret
ILGenerator setterILCode = setterMethod.GetILGenerator();
setterILCode.Emit(OpCodes.Ldarg_0);
setterILCode.Emit(OpCodes.Ldarg_1);
setterILCode.Emit(OpCodes.Stfld, fieldBuilder);
setterILCode.Emit(OpCodes.Ret);
propertyBuilder.SetGetMethod(getterMethod);
propertyBuilder.SetSetMethod(setterMethod);
}
public static dynamic SqlFunctionForDynamic(this Database db,
string sql,
params object[] parameters)
{
IDbConnection conn = DefaultConnection;
//ADO.NET数据库连接字符串
conn.ConnectionString = DefaultConnectionString;
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
IDbCommand cmd = conn.CreateCommand();
cmd.CommandText = sql;
cmd.CommandType = CommandType.StoredProcedure;
if (parameters != null)
{
foreach (var item in parameters)
{
cmd.Parameters.Add(item);
}
}
//1、DataReader查询数据
using (IDataReader dataReader = cmd.ExecuteReader())
{
if (!dataReader.Read())
{
return null;
}
//2、DataReader转换Json
string jsonstr = JsonConverter.ToJson(dataReader);
dataReader.Close();
dataReader.Dispose();
cmd.Dispose();
conn.Close();
conn.Dispose();
//3、Json转换动态类
dynamic dyna = JsonConverter.ConvertJson(jsonstr);
return dyna;
}
}
///
/// 对可空类型进行判断转换(*要不然会报错)
///
/// DataReader字段的值
/// 该字段的类型
///
private static object CheckType(object value, Type conversionType)
{
if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
if (value == null)
return null;
System.ComponentModel.NullableConverter nullableConverter = new System.ComponentModel.NullableConverter(conversionType);
conversionType = nullableConverter.UnderlyingType;
}
return Convert.ChangeType(value, conversionType);
}
///
/// 判断指定对象是否是有效值
///
///
///
private static bool IsNullOrDBNull(object obj)
{
return (obj == null || (obj is DBNull)) ? true : false;
}
}
}