【问题标题】:How to execute a stored procedure returning a pivot table in Web API如何在 Web API 中执行返回数据透视表的存储过程
【发布时间】:2020-09-06 12:16:46
【问题描述】:

如何执行返回数据透视表的存储过程并在 API 中以 JSON 格式返回数据。我想使用 API 在网页上显示其数据。我得到的只是一个对象列表,而不是其中的数据。 我的程序在其中返回 983 条表行记录...但是根据传递的参数更改列 所以对于一种参数我可以有 20 列购买另一种我可以只有 1 通过使用执行程序

    var ls = db.Database.SqlQuery<dynamic>("exec [Sp_StoreItemParty] 'Amount','01-Apr-2020', '06-Sep-2020','', '', '', ''").ToList();
    return Json(ls, JsonRequestBehavior.AllowGet);

如何执行返回数据透视表的存储过程并将其作为 Web API 以 JSON 格式返回。我得到的只是一个对象列表,但没有一个对象可以在 Firefox 上的 Postman 中进一步访问或进一步显示。

【问题讨论】:

    标签: c# stored-procedures visual-studio-2015 asp.net-apicontroller jsonresult


    【解决方案1】:

    SqlQuery 仅适用于已知类型,不适用于 dynamic。你可以

    1. 要么创建一个代表您的结果记录的类并使用它。或者

    2. 使用here 所示的数据阅读器并复制粘贴到下方。

      public static IEnumerable<dynamic> CollectionFromSql(this DbContext dbContext, string Sql, Dictionary<string, object> Parameters)
      {
          using (var cmd = dbContext.Database.GetDbConnection().CreateCommand())
          {
              cmd.CommandText = Sql;
              if (cmd.Connection.State != ConnectionState.Open)
                  cmd.Connection.Open();
      
              foreach (KeyValuePair<string, object> param in Parameters)
              {
                  DbParameter dbParameter = cmd.CreateParameter();
                  dbParameter.ParameterName = param.Key;
                  dbParameter.Value = param.Value;
                  cmd.Parameters.Add(dbParameter);
              }
      
              //var retObject = new List<dynamic>();
              using (var dataReader = cmd.ExecuteReader())
              {
      
                  while (dataReader.Read())
                  {
                      var dataRow = GetDataRow(dataReader);
                      yield return dataRow ;
      
                  }
              }
      
      
          }
      }
      
      private static dynamic GetDataRow(DbDataReader dataReader)
      {
          var dataRow = new ExpandoObject() as IDictionary<string, object>;
          for (var fieldCount = 0; fieldCount < dataReader.FieldCount; fieldCount++)
              dataRow.Add(dataReader.GetName(fieldCount), dataReader[fieldCount]);
          return dataRow;
      }
      

      用法:

      List<dynamic> MyList = MyDbContext.CollectionFromSql("SELECT * FROM \"User\" WHERE UserID = @UserID",
          new Dictionary<string, object> { { "@UserID", 1 } }).ToList();
      

    【讨论】:

      【解决方案2】:

      因为你的对象是动态对象,你必须在运行时通过反射来解析对象的结构。

      然后,当您拥有对象的每个属性的名称和值时,您可以手动构建您的 json。

      Type myType = myObject.GetType();
      IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties());
      
      foreach (PropertyInfo prop in props)
      {
          String propName = prop.name;
          object propValue = prop.GetValue(myObject, null);
      
          // Do something with propValue
      }
      

      小提示: 反射可以是非常有效且该死的复杂逻辑。 如果您可以更改存储过程以返回列的固定子集,它将更快更简单。

      【讨论】:

        【解决方案3】:

        1.首先您需要创建数据传输对象。 2.添加DbContext Datatransfer对象 公共 DbQuery YourClass { 获取;放; } 3.var data = db.YourClass.FromSql("EXEC DashBoard").ToList();

        注意除了实体类型之外,EF Core 模型还可以包含查询类型,这些查询类型可用于针对未映射到实体类型的数据执行数据库查询。

        什么时候使用查询类型?

        作为临时 FromSql() 查询的返回类型。

        映射到数据库视图。

        映射到没有定义主键的表。

        映射到模型中定义的查询。

        【讨论】:

        • 使用get set 创建一个类只有在我有特定的列在程序中返回时才有效。无法确定会有 20 列还是 100 列。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-09-01
        • 2021-09-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-04
        • 1970-01-01
        相关资源
        最近更新 更多