DynamicSqlQuery.cs 3.8 KB

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