EF 6.x和EF Core实现返回dynamic类型
Core 实现 类型 返回 Dynamic ef
2023-09-11 14:13:57 时间
前言
未曾想需要直接返回dynamic,多次尝试未能实现,最终还是在stackoverflow上找到了解决方案,特此备忘录。
public static dynamic SqlQuery(this Database database, string sql, params object[] parameters) { TypeBuilder builder = CreateTypeBuilder( "DynamicAssembly", "DynamicModule", "DynamicType"); using (var cmd = database.Connection.CreateCommand()) { try { cmd.CommandText = sql; if (cmd.Connection.State != ConnectionState.Open) { cmd.Connection.Open(); } cmd.CommandTimeout = cmd.Connection.ConnectionTimeout; foreach (var param in parameters) { cmd.Parameters.Add(param); } using (IDataReader reader = cmd.ExecuteReader()) { var schema = reader.GetSchemaTable(); foreach (DataRow row in schema.Rows) { var name = (string)row["ColumnName"]; var type = (Type)row["DataType"]; if (type != typeof(string) && (bool)row.ItemArray[schema.Columns.IndexOf("AllowDbNull")]) { type = typeof(Nullable<>).MakeGenericType(type); } CreateAutoImplementedProperty(builder, name, type); } } } finally { database.Connection.Close(); cmd.Parameters.Clear(); } } var resultType = builder.CreateType(); return database.SqlQuery(resultType, sql, parameters); } 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, System.Reflection.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); }
using (var ctx = new EfDbContext()) { ctx.Database.Log = Console.WriteLine; dynamic queryResult = ctx.Database.SqlQuery("select o.*,c.Name from dbo.Orders as o left join dbo.Customers as c on o.CustomerId = c.Id"); var ordersJson = JsonConvert.SerializeObject(queryResult); var orders = JsonConvert.DeserializeObject<List<Order>>(ordersJson); };
相关文章
- EntityFramework Core 2.0执行原始查询如何防止SQL注入?
- EntityFramework Core不得不注意的性能优化意外收获,你会用错?
- 学习ASP.NET Core Blazor编程系列文章之目录
- abp(net core)+easyui+efcore实现仓储管理系统——出库管理之二(五十)
- abp(net core)+easyui+efcore实现仓储管理系统——出库管理之一(四十九)
- abp(net core)+easyui+efcore实现仓储管理系统——入库管理之十一(四十七)
- abp(net core)+easyui+efcore实现仓储管理系统——入库管理之八(四十四)
- abp(net core)+easyui+efcore实现仓储管理系统——入库管理之五(四十一)
- abp(net core)+easyui+efcore实现仓储管理系统——ABP WebAPI与EasyUI结合增删改查之九(三十五)
- abp(net core)+easyui+efcore实现仓储管理系统——ABP WebAPI与EasyUI结合增删改查之六(三十二)
- abp(net core)+easyui+efcore实现仓储管理系统——ABP WebAPI与EasyUI结合增删改查之二(二十八)
- abp(net core)+easyui+efcore实现仓储管理系统——EasyUI之货物管理六(二十四)
- abp(net core)+easyui+efcore实现仓储管理系统——使用 WEBAPI实现CURD (十五)
- abp(net core)+easyui+efcore实现仓储管理系统目录
- 学习ASP.NET Core Razor 编程系列二——添加一个实体
- Reactor:深入理解reactor core
- .Net Core ORM选择之路,哪个才适合你 通用查询类封装之Mongodb篇 Snowflake(雪花算法)的JavaScript实现 【开发记录】如何在B/S项目中使用中国天气的实时天气功能 【开发记录】微信小游戏开发入门——俄罗斯方块
- 【23种设计模式】解释器模式(Interpreter Pattern) .Net Core实现
- 【23种设计模式】原型模式(Prototype Pattern) .Net Core实现
- 关于core_cm3.c和core_cm3.h,Core_cmFunc.h 和 Core_cmInstr.h的理解
- ASP.NET Core应用程序的参数配置及使用
- 【HMS Core】运动健康服务设置回调地址,出现连接失败
- ASP.NET Core 1.0开发Web API程序
- 【HMS Core】华为分析kit如果调用getInstance()不指定数据处理位置,那么SDK是如何选择上传位置的?
- 【HMS Core】音频编辑服务带你实现音源分离与合成
- 【有奖评论】HMS Core.Sparkle创新沙龙来啦,参与互动赢华为三脚架自拍杆(无线版)
- ASP.NET Core 中的 Request Feature