zoukankan      html  css  js  c++  java
  • 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<>);
        }
     
    }
     
  • 相关阅读:
    OpenCascade Ray Tracing Rendering
    Create New Commands in Tcl
    OpenCascade Modeling Algorithms Fillets and Chamfers
    OpenCascade Modeling Algorithms Boolean Operations
    Construction of Primitives in Open Cascade
    Open Cascade Data Exchange STL
    Tcl Tk Introduction
    Open Cascade DataExchange IGES
    Netgen mesh library : nglib
    Hello Netgen
  • 原文地址:https://www.cnblogs.com/xiajing12345/p/7307724.html
Copyright © 2011-2022 走看看