ASP.NET Core Entity Framework SQL Query SELECT
我是从ASP.NET到ASP.NET Core进行"升级"的众多努力之一。
在ASP.NET项目中,我像这样从DAL进行数据库调用:
1 2 3 4 5 | var result = context.Database.SqlQuery<Object_VM>("EXEC [sp_Object_GetByKey] @Key", new SqlParameter("@Key", Key)) .FirstOrDefault(); return result; |
我的视图模型具有我的对象没有的其他字段,例如相关表的集合。在数据库/表结构中包含此类字段似乎是不必要的,而且非常直观。我的存储过程将计算所有这些内容并返回应显示但不存储的字段。
我看到ASP.NET Core删除了此功能。我试图继续使用存储过程和加载视图模型(因此在数据库中没有实体)。我看到类似以下的选项,但结果是得到" 2 ",即返回的行数(或另一个神秘的结果?)。
1 2 3 4 5 | using(context) { string cmd ="EXEC [sp_Object_getAll]"; var result = context.Database.ExecuteSQLCommand(cmd); } |
但这不会起作用,因为
我也已经将以下内容视为解决方案,但是代码不会为我编译,因为" set "实际上是
1 | var result = context.Set().FromSql("EXEC [sp_Object_getAll]"); |
非常感谢任何帮助。
解决方案:
(按照曾梵志的建议)
在GitHub Entity Framework Issues页面上,有关于此问题的讨论。一个用户建议创建自己的类来处理此类请求,另一个用户建议添加其他方法以使其运行更加流畅。我更改了方法参数以接受稍有不同的参数。
这是我的适应内容(差异很小),对于其他也在寻找解决方案的人:
DAL中的方法
1 2 3 4 5 6 | public JsonResult GetObjectByID(int ID) { SqlParameter[] parms = new SqlParameter[] { new SqlParameter("@ID", ID) }; var result = RDFacadeExtensions.GetModelFromQuery<Object_List_VM>(context,"EXEC [sp_Object_GetList] @ID", parms); return new JsonResult(result.ToList(), setting); } |
其他课程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | public static class RDFacadeExtensions { public static RelationalDataReader ExecuteSqlQuery( this DatabaseFacade databaseFacade, string sql, SqlParameter[] parameters) { var concurrencyDetector = databaseFacade.GetService<IConcurrencyDetector>(); using (concurrencyDetector.EnterCriticalSection()) { var rawSqlCommand = databaseFacade .GetService<IRawSqlCommandBuilder>() .Build(sql, parameters); return rawSqlCommand .RelationalCommand .ExecuteReader( databaseFacade.GetService<IRelationalConnection>(), parameterValues: rawSqlCommand.ParameterValues); } } public static IEnumerable< T > GetModelFromQuery< T >( DbContext context, string sql, SqlParameter[] parameters) where T : new() { DatabaseFacade databaseFacade = new DatabaseFacade(context); using (DbDataReader dr = databaseFacade.ExecuteSqlQuery(sql, parameters).DbDataReader) { List< T > lst = new List< T >(); PropertyInfo[] props = typeof(T).GetProperties(); while (dr.Read()) { T t = new T(); IEnumerable<string> actualNames = dr.GetColumnSchema().Select(o => o.ColumnName); for (int i = 0; i < props.Length; ++i) { PropertyInfo pi = props[i]; if (!pi.CanWrite) continue; System.ComponentModel.DataAnnotations.Schema.ColumnAttribute ca = pi.GetCustomAttribute(typeof(System.ComponentModel.DataAnnotations.Schema.ColumnAttribute)) as System.ComponentModel.DataAnnotations.Schema.ColumnAttribute; string name = ca?.Name ?? pi.Name; if (pi == null) continue; if (!actualNames.Contains(name)) { continue; } object value = dr[name]; Type pt = pi.DeclaringType; bool nullable = pt.GetTypeInfo().IsGenericType && pt.GetGenericTypeDefinition() == typeof(Nullable<>); if (value == DBNull.Value) { value = null; } if (value == null && pt.GetTypeInfo().IsValueType && !nullable) { value = Activator.CreateInstance(pt); } pi.SetValue(t, value); }//for i lst.Add(t); }//while return lst; }//using dr } |