【问题标题】:asp.net mvc , raw sql : Display data in Views generated using aggregate functionasp.net mvc,raw sql:在使用聚合函数生成的视图中显示数据
【发布时间】:2015-10-24 04:56:45
【问题描述】:

我正在使用 ASP.NET MVC、EF 6 和 SQL Server 2008。

我想生成一个视图,该视图将显示特定年份中特定月份每天所有销售额的总和。

我发现在这种类型的工作中 LINQ 查询非常复杂,所以我使用了原始 SQL 查询。我编写了查询并在 SQL Server 中进行了测试,它运行良好。

select  
    YEAR(Date) as Year, 
    MONTH(Date) as month, 
    DAY(Date) as date,   
    SUM(GrandTotal) as Total  
from 
    Sales 
where 
    Year(Date) = 2014 
    and MONTH(Date) = 12 
group by 
    DAY(Date), YEAR(Date), MONTH(date)

结果

目前我没有太多数据。但看起来我从查询中得到了我想要的东西。

我为此编写了一个控制器,但现在我不知道如何在 View 中显示这些数据。

public ActionResult MonthlySalesByDate()
{
        DateTime today = DateTime.Now.Date;
        int _year = today.Year;
        int _month = today.Month;

        //raw sql query 
        string query = "select SUM(GrandTotal) as Total, DAY(Date) as date, MONTH(Date) as month, YEAR(Date) as Year from Sales where Year(Date) = " + _year + " and MONTH(Date) =" + _month + "  Group by DAY(Date), YEAR(Date), MONTH(date)";

        //executing raw sql query 
        var _model = db.Stocks.SqlQuery(query).ToList();           

        return View(_model);
}

请帮我解决这个问题。如果有更好的方法或者我犯了错误,请告诉我。

【问题讨论】:

  • 你想怎么显示?月份和年份的标题和表格?表格应该是什么样子(天和总计的列,或每天的列)?
  • 我想显示为列:|日期 |总销售额 | .如果日期列以升序包含该月中的所有日期以及各自的总销售额,并且如果特定日期没有销售,则显示 0 会更好。
  • 如果您只想要带有金额的天数(即模仿您的 sql 查询),则获取天数及其总数的 linq 查询相对简单。我会考虑如何在一个月的所有日子里生成它
  • 我应该如何在视图中显示它?我必须为此创建一个视图模型吗?好吧,主要要求是生成包含当月所有日期和相应销售额的视图。
  • 是的,您需要一个视图模型。我会尽快发布答案。

标签: sql sql-server asp.net-mvc entity-framework-6


【解决方案1】:

首先创建视图模型来表示您想要在视图中显示的内容

public class DayTotalVM
{
  public int Day { get; set; }
  [DisplayFormat(DataFormatString = "{0:C}")]
  public decimal Total { get; set; }
}
public class SalesVM
{
  [DisplayFormat(DataFormatString = "{0:MMMM yyyy}")]
  public DateTime Date { get; set; }
  public List<DayTotalVM> Days { get; set; }
}

您拥有的 sql 查询可以在 linq 中生成并投射到您的视图模型中使用

int year = 2014;
int month = 12;
var query = db.Sales.Where(x => x.Date.Year == year && x.Date.Month == month)
    .GroupBy(x => x.Date).Select(g => new DayTotalVM
    {
        Day = g.Key.Day,
        Total = g.Sum(x => x.Total)
    })

但是,这只会为您提供上图所示的 2 个项目,但来自您想要显示该月所有日期的 cmets,因此您可以添加

int daysInMonth = DateTime.DaysInMonth(year, month);
List<DayTotalVM> days = new List<DayTotalVM>();
for(int i = 1; i < daysInMonth + 1; i++)
{
    DayTotalVM item = new DayTotalVM () { Day = i };
    DayTotalVM ex = query.Where(x => x.Day == i).FirstOrDefault();
    if (ex != null)
    {
        item.Total = ex.Total;
    }
    days.Add(item);
}

最后初始化并返回你的视图模型

SalesVM model = new SalesVM();
{
  Date = new DateTime(year, month, 1),
  Days = days 
}
return View(model);

然后视图将是

@model SalesVM
@Html.DisplayFor(m => m.Date);
<table>
  @for(int i = 0; i < Model.Days.Count; i++)
  {
    <tr>
      <td>@Html.DisplayFor(m => m.Days[i].Day)</td>
      <td>@Html.DisplayFor(m => m.Days[i].Total)</td>
    </tr>
  }
</table>

编辑

for 循环可以使用 GroupJoin() 替换

public ActionResult MonthlySalesByDate(int year, int month)
{
  int daysInMonth = DateTime.DaysInMonth(year, month);
  var days = Enumerable.Range(1, daysInMonth);
  var query = db.Sales.Where(x => x.Date.Year == year && x.Date.Month == month).Select(g => new
  {
    Day = g.Date.Day,
    Total = g.Total
  });
  var model = new SalesVM
  {
    Date = new DateTime(year, month, 1),
    Days = days.GroupJoin(query, d => d, q => q.Day, (d, q) => new DayTotalVM
    {
      Day = d,
      Total = q.Sum(x => x.Total)
    }).ToList()
  };
  return View(model);
}

【讨论】:

  • 太棒了!!一如既往地感谢斯蒂芬.. :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-21
  • 1970-01-01
  • 1970-01-01
  • 2017-09-02
相关资源
最近更新 更多