EF使用动态类型

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.Collections; using System.Reflection.Emit; using System.Reflection; namespace Demo { public class Program { public static void Main(string[] args) { string connectionString = "Server=(local); Integrated Security=true; Database=master"; using (DbContext context = new DbContext(connectionString)) { TypeBuilder builder = Program.CreateTypeBuilder( "MyDynamicAssembly", "MyModule", "MyType"); Program.CreateAutoImplementedProperty(builder, "name", typeof(string)); Program.CreateAutoImplementedProperty(builder, "type", typeof(string)); Program.CreateAutoImplementedProperty(builder, "id", typeof(int)); Type resultType = builder.CreateType(); dynamic queryResult = context.Database.SqlQuery( resultType, "SELECT * FROM sys.sysobjects"); Console.WriteLine("{0,20} {1,4} {2,10}", "Name", "Type", "ID"); foreach (dynamic item in queryResult) { Console.WriteLine("{0,10} {1,4} {2,10}", item.name, item.type, item.id); } } Console.ReadKey(); } 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; } 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, 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); } } }
  /// <summary>
        /// Reads database schema from query, generates assembly in the memory, and returns dynamic object /// </summary> public static System.Collections.IEnumerable DynamicSqlQuery(this Database database, string sql, params object[] parameters) { TypeBuilder builder = DynamicMapper.createTypeBuilder( "MyDynamicAssembly", "MyDynamicModule", "MyDynamicType");   using (System.Data.IDbCommand command = database.Connection.CreateCommand()) { try { database.Connection.Open(); command.CommandText = sql; command.CommandTimeout = command.Connection.ConnectionTimeout; foreach (var param in parameters) { command.Parameters.Add(param); }   using (System.Data.IDataReader reader = command.ExecuteReader()) { var schema = reader.GetSchemaTable(); foreach (System.Data.DataRow row in schema.Rows) { string name = (string)row["ColumnName"]; Type type = (Type)row["DataType"]; DynamicMapper.createAutoImplementedProperty(builder, name, type); } } } finally { database.Connection.Close(); command.Parameters.Clear(); } }   Type resultType = builder.CreateType();   return database.SqlQuery(resultType, sql, parameters); }   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; }   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, 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 class DynamicMapper
{
    private static Dictionary<string, Type> baseEntityTypesByType = new Dictionary<string, Type>();   public static System.Collections.IEnumerable DynamicSqlQuery(this Database database, string sql, params object[] parameters) {   Type resultType;   if (baseEntityTypesByType.TryGetValue(sql, out resultType)) { Console.WriteLine("Inside Got the Type"); if (parameters != null) return database.SqlQuery(resultType, sql, parameters); return database.SqlQuery(resultType, sql); }   TypeBuilder builder = DynamicMapper.createTypeBuilder( "MyDynamicAssembly", "MyDynamicModule", "MyDynamicType");   using (System.Data.IDbCommand command = database.Connection.CreateCommand()) { try { database.Connection.Open(); command.CommandText = sql; command.CommandTimeout = command.Connection.ConnectionTimeout; if (parameters != null) { foreach (var param in parameters) { command.Parameters.Add(param); } }   using (System.Data.IDataReader reader = command.ExecuteReader()) { var schema = reader.GetSchemaTable(); foreach (System.Data.DataRow row in schema.Rows) { string name = (string)row["ColumnName"]; Type type = (Type)row["DataType"]; var allowNull = (bool) row["AllowDBNull"]; if (allowNull) { type = GetNullableType(type); } DynamicMapper.createAutoImplementedProperty(builder, name, type); } } } finally { database.Connection.Close(); command.Parameters.Clear(); } }   resultType = builder.CreateType(); baseEntityTypesByType[sql] = resultType;   if (parameters!=null) return database.SqlQuery(resultType, sql, parameters);   return database.SqlQuery(resultType,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; }   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, 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 Type GetNullableType(Type TypeToConvert) { // Abort if no type supplied if (TypeToConvert == null) return null;   // If the given type is already nullable, just return it if (IsTypeNullable(TypeToConvert)) return TypeToConvert;   // If the type is a ValueType and is not System.Void, convert it to a Nullable<Type> if (TypeToConvert.IsValueType && TypeToConvert != typeof(void)) return typeof(Nullable<>).MakeGenericType(TypeToConvert);   // Done - no conversion return null; } public static bool IsTypeNullable(Type TypeToTest) { // Abort if no type supplied if (TypeToTest == null) return false;   // If this is not a value type, it is a reference type, so it is automatically nullable // (NOTE: All forms of Nullable<T> are value types) if (!TypeToTest.IsValueType) return true;   // Report whether TypeToTest is a form of the Nullable<> type return TypeToTest.IsGenericType && TypeToTest.GetGenericTypeDefinition() == typeof(Nullable<>); }   }
 

转载于:https://www.cnblogs.com/xiajing12345/p/7307724.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值