zoukankan      html  css  js  c++  java
  • 如何把匿名类型.GetType()返回的对象传进泛型里面

    //怎么取得匿名类型的Type放到
    //泛型T当中??
    
    var 匿名 = new {
     A = 0,
     B = 1 };
    Type t = 匿名.GetType();
    
    //然后下面
    var xx = dbContext.Database.SqlQuery<t>("sql");
    //就悲剧了
    
    var xx2 = dbContext.Database.SqlQuery<dynamic>("sql");
    //xx2有列表,但是都是Object..~~~无法显示真实项,用Profile跟..SQL确实提交了.
    求解释

    msdn大神的解决办法

    看到了所以记录下来

    出现那个问题的原因是动态类型上没有 Entity Framework 需要的属性定义,Entity Framework 是通过反射类型上的属性来做映射的。为了解决这个问题,我用到了 Emit 技术,动态产生一个类型,并且动态写入 IL 代码产生属性。
    
    代码如下,测试在 C# 4.0 上通过。
    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);
        }
      }
    }
  • 相关阅读:
    解剖PetShop系列之六PetShop表示层设计
    解剖PetShop系列之五PetShop之业务逻辑层设计
    用memset给一个char设置0xff,然后将该char和0xff ==,能相等么?
    用gdb如何查看指定地址的内存内容?
    Open a pipe will block if other side hasn't opened this pipe
    inet_aton和inet_pton的区别
    很多源码中看到的ignore SIGCHLD信号是做什么用的?
    Linux下getopt函数使用Tips
    Linux下编译一个静态链接的程序的注意点
    Linux 脚本和程序对SIGINT的处理方案,脚本通过kill给程序传递信号
  • 原文地址:https://www.cnblogs.com/0banana0/p/2484698.html
Copyright © 2011-2022 走看看