c# – sql查询执行实体框架的匿名类型结果

前端之家收集整理的这篇文章主要介绍了c# – sql查询执行实体框架的匿名类型结果前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我使用实体框架5.0与.net框架4.0代码第一种方法.现在我知道我可以通过以下方式在实体框架中运行raw sql
  1. var students = Context.Database.sqlQuery<Student>("select * from student").ToList();

它的工作完美,但我想要的是返回匿名结果.例如,我只想要学生表中的特定列,如下所示

  1. var students = Context.Database.sqlQuery<Student>("select FirstName from student").ToList();

它不工作它给出例外

The data reader is incompatible with the specified ‘MyApp.DataContext.Student’. A member of the type,‘StudentId’,does not have a corresponding column in the data reader with the same name.

所以我尝试了动态类型

  1. var students = Context.Database.sqlQuery<dynamic>("select FirstName from student").ToList();

它也不工作,它返回一个空对象.没有可用的数据.

有没有办法从动态SQL查询获取匿名类型的结果?

解决方法

以上解决方案对我来说很好,但是当我尝试获取Nullable类型列时,它有一些问题.

这是我的最终解决方案.

  1. public static System.Collections.IEnumerable DynamicsqlQuery(this Database database,string sql,params object[] parameters)
  2. {
  3. TypeBuilder builder = createTypeBuilder(
  4. "MyDynamicAssembly","MyDynamicModule","MyDynamicType");
  5.  
  6. using (System.Data.IDbCommand command = database.Connection.CreateCommand())
  7. {
  8. try
  9. {
  10. database.Connection.Open();
  11. command.CommandText = sql;
  12. command.CommandTimeout = command.Connection.ConnectionTimeout;
  13. foreach (var param in parameters)
  14. {
  15. command.Parameters.Add(param);
  16. }
  17.  
  18. using (System.Data.IDataReader reader = command.ExecuteReader())
  19. {
  20. var schema = reader.GetSchemaTable();
  21.  
  22. foreach (System.Data.DataRow row in schema.Rows)
  23. {
  24. string name = (string)row["ColumnName"];
  25. //var a=row.ItemArray.Select(d=>d.)
  26. Type type = (Type)row["DataType"];
  27. if(type!=typeof(string) && (bool)row.ItemArray[schema.Columns.IndexOf("AllowDbNull")])
  28. {
  29. type = typeof(Nullable<>).MakeGenericType(type);
  30. }
  31. createAutoImplementedProperty(builder,name,type);
  32. }
  33. }
  34. }
  35. finally
  36. {
  37. database.Connection.Close();
  38. command.Parameters.Clear();
  39. }
  40. }
  41.  
  42. Type resultType = builder.CreateType();
  43.  
  44. return database.sqlQuery(resultType,sql,parameters);
  45. }
  46.  
  47. private static TypeBuilder createTypeBuilder(
  48. string assemblyName,string moduleName,string typeName)
  49. {
  50. TypeBuilder typeBuilder = AppDomain
  51. .CurrentDomain
  52. .DefineDynamicAssembly(new AssemblyName(assemblyName),AssemblyBuilderAccess.Run)
  53. .DefineDynamicModule(moduleName)
  54. .DefineType(typeName,TypeAttributes.Public);
  55. typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);
  56. return typeBuilder;
  57. }
  58.  
  59. private static void createAutoImplementedProperty(
  60. TypeBuilder builder,string propertyName,Type propertyType)
  61. {
  62. const string PrivateFieldPrefix = "m_";
  63. const string GetterPrefix = "get_";
  64. const string SetterPrefix = "set_";
  65.  
  66. // Generate the field.
  67. FieldBuilder fieldBuilder = builder.DefineField(
  68. string.Concat(PrivateFieldPrefix,propertyName),propertyType,FieldAttributes.Private);
  69.  
  70. // Generate the property
  71. PropertyBuilder propertyBuilder = builder.DefineProperty(
  72. propertyName,System.Reflection.PropertyAttributes.HasDefault,null);
  73.  
  74. // Property getter and setter attributes.
  75. MethodAttributes propertyMethodAttributes =
  76. MethodAttributes.Public | MethodAttributes.SpecialName |
  77. MethodAttributes.HideBySig;
  78.  
  79. // Define the getter method.
  80. MethodBuilder getterMethod = builder.DefineMethod(
  81. string.Concat(GetterPrefix,propertyMethodAttributes,Type.EmptyTypes);
  82.  
  83. // Emit the IL code.
  84. // ldarg.0
  85. // ldfld,_field
  86. // ret
  87. ILGenerator getterILCode = getterMethod.GetILGenerator();
  88. getterILCode.Emit(OpCodes.Ldarg_0);
  89. getterILCode.Emit(OpCodes.Ldfld,fieldBuilder);
  90. getterILCode.Emit(OpCodes.Ret);
  91.  
  92. // Define the setter method.
  93. MethodBuilder setterMethod = builder.DefineMethod(
  94. string.Concat(SetterPrefix,null,new Type[] { propertyType });
  95.  
  96. // Emit the IL code.
  97. // ldarg.0
  98. // ldarg.1
  99. // stfld,_field
  100. // ret
  101. ILGenerator setterILCode = setterMethod.GetILGenerator();
  102. setterILCode.Emit(OpCodes.Ldarg_0);
  103. setterILCode.Emit(OpCodes.Ldarg_1);
  104. setterILCode.Emit(OpCodes.Stfld,fieldBuilder);
  105. setterILCode.Emit(OpCodes.Ret);
  106.  
  107. propertyBuilder.SetGetMethod(getterMethod);
  108. propertyBuilder.SetSetMethod(setterMethod);
  109. }

猜你在找的C#相关文章