• 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<>);
        }
     
    }
     
  • 相关阅读:
    【UVA11324】 The Largest Clique (Tarjan+topsort/记忆化搜索)
    【洛谷2245】 星际导航 (最小瓶颈路)
    【UVA10816】Travel in Desert (最小瓶颈路+最短路)
    【洛谷 5002】专心OI
    炸金花【大模拟】
    【BZOJ1055】[HAOI2008]玩具取名(区间DP)
    【BZOJ1296】[SCOI2009]粉刷匠 (DP+背包)
    NOIP前的模板
    获取<考试>博文密码!o(*≧▽≦)ツ
    这是个萌新的萌新博客
  • 原文地址:https://www.cnblogs.com/xiajing12345/p/7307724.html
Copyright © 2020-2023  润新知