如何把匿名类型.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);
    }
  }
}
posted @ 2012-05-05 13:44  一个土豆一棵青菜  阅读(4472)  评论(1编辑  收藏  举报