1、测试示例
/** 使用Emit动态生成代码 **/
//创建程序集
var builder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("EmitTest"), AssemblyBuilderAccess.RunAndSave);
//创建模块
var module = builder.DefineDynamicModule("Main", "Main.exe");
//定义类
var type = module.DefineType("Hello", TypeAttributes.Public) ;
//定义方法 (方法名、访问属性、返回值、参数)
var method = type.DefineMethod("SayHello", MethodAttributes.Public | MethodAttributes.Static, null, null);
//获取IL生成器
var il = method.GetILGenerator();
il.Emit(OpCodes.Ldstr, "Hello world");//ldStr:加载一个字符串到evaluation stack。
il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));//Call:调用方法。
il.Emit(OpCodes.Call, typeof(Console).GetMethod("ReadLine"));
il.Emit(OpCodes.Pop);//读入的值会被推送至evaluation stack,而本方法是没有返回值的,因此,需要将栈上的值抛弃
il.Emit(OpCodes.Ret);//Ret:返回,当evaluation stack有值时会返回栈顶值。
var t = type.CreateType();
builder.SetEntryPoint(t.GetMethod("SayHello"));
builder.Save("Main.exe");
2、链接数据库,sql查询视图生成动态类
public static IEnumerable SqlQueryForDynamic(this Database db,
string sql,
params object[] parameters)
{
IDbConnection defaultConn = new System.Data.SqlClient.SqlConnection();
return SqlQueryForDynamicOtherDB(db, sql, defaultConn, parameters);
}
/// <summary>
/// 获取集合
/// </summary>
/// <param name="db"></param>
/// <param name="sql"></param>
/// <param name="conn"></param>
/// <param name="parameters"></param>
/// <returns></returns>
public static IList 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;
IDataReader dataReader = cmd.ExecuteReader();
if (!dataReader.Read())
{
return null; //无结果返回Null
}
TypeBuilder builder = DatabaseExtensions.CreateTypeBuilder(
"EF_DynamicModelAssembly",
"DynamicModule",
"DynamicType");
int fieldCount = dataReader.FieldCount;
for (int i = 0; i < fieldCount; i++)
{
DatabaseExtensions.CreateAutoImplementedProperty(
builder,
dataReader.GetName(i),
dataReader.GetFieldType(i));
}
dataReader.Close();
dataReader.Dispose();
cmd.Dispose();
conn.Close();
conn.Dispose();
Type returnType = builder.CreateType();
if (parameters != null)
{
var res = db.SqlQuery(returnType, sql, parameters).ToListAsync();
return res.Result;
}
else
{
return db.SqlQuery(returnType, sql).ToListAsync().Result;
}
}
/// <summary>
/// 类型创建
/// </summary>
/// <param name="assemblyName"></param>
/// <param name="moduleName"></param>
/// <param name="typeName"></param>
/// <returns></returns>
public 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;
}
/// <summary>
/// 创建属性
/// </summary>
/// <param name="builder"></param>
/// <param name="propertyName"></param>
/// <param name="propertyType"></param>
public 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);
}
}
3、执行
IEnumerable result = db.Database.SqlQueryForDynamic("select * from Users");
//IEnumerable result = db.Database.SqlQueryForDynamic("select cast([text] as int) id from str_spit('1,4,77,4,2,1,2,3555,3,2')");
foreach (var cq in result)
{
Type type = cq.GetType();
PropertyInfo[] propertyInfos = type.GetProperties();
foreach (PropertyInfo item in propertyInfos)
{
Console.WriteLine("Name: {0};Value:{1}",item.Name, (item.GetValue(cq, null) == null ? "" : item.GetValue(cq, null)));
}
}
