【问题标题】:Grouping By Month from String Date using LINQ使用 LINQ 从字符串日期按月份分组
【发布时间】:2018-08-20 13:07:00
【问题描述】:

我正在为 GroupBy 按月记录做很多不必要的工作。在数据库中,日期以varchar 格式保存,现在我无法更改格式,因为很多东西都依赖于它。以下是我的代码:

var Job_Progress_ViewModel = new List<MyViewModel>();

var Job_Ids = new List<int?>();

var Jobs = db.Jobs.Where(x.Date != null).ToList();

foreach (var job in Jobs)
{
   int Year = Year_from_strDate(job.Date);
   if (Year == 2018)
   {
      Job_Ids .Add(order.Id);
   }
}

var JobProgress = db.JobProgress.Where(x => Job_Ids.Contains(x.JobId)).ToList();

foreach(var record in JobProgress)
{
   var Model = new MyViewModel()
   {
       Month = Month_From_strDate(record.Job.Date),
       Amount = record.total
   };
   Job_Progress_ViewModel.Add(Model);
}

在我看来:

foreach (var month in Model.Select(x=>x.Month).Distinct())
{
   <tr>
     <td>
        @Model.Where(x => x.Month == month).Sum(x => x.Amount))
     </td>
   </tr>
}

我认为这不是好方法。然后我在互联网上搜索,并尝试了以下代码:

db.JobProgress.Where(x => Job_Ids.Contains(x.JobId))
.GroupBy(x => Month_From_strDate(x.Job.Date)
.Select(ln => new MyViewModel
{
   Month = // How can I add month Here,
   Amount = ln.Sum(r => r.total)
}).ToList();

我发现它更好的方法,但这里有两个问题:

  1. 我不知道如何获取月份,
  2. 而且我不能使用日期转换功能。我收到以下有效错误:

LINQ to Entities 无法识别方法 'System.String ToString()'

由于无法更改数据库中的日期格式,我该如何解决这个问题?

【问题讨论】:

  • varchar中的日期是什么格式?
  • dd-mm-yyyy格式。

标签: asp.net-mvc entity-framework linq group-by


【解决方案1】:

在数据库中将datetime 存储为varchar 是非常糟糕的主意。管理它们会非常困难,并且像这个例子一样让你头疼。所以,我强烈建议你不惜一切代价将其转换为datetime 类型。

因此,在您的情况下,您可以尝试使用SqlFunctions.DateAddvarchar 解析为datetimegroup,使用SqlFunctions.DatePart

db.JobProgress.Where(x => Job_Ids.Contains(x.JobId))
.GroupBy(x => SqlFunctions.DatePart("month", SqlFunctions.DateAdd("day", 0, x.Job.Date)))
.Select(ln => new MyViewModel
{
   Month = ln.Key
   Amount = ln.Sum(r => r.total)
}).ToList();

如果解析日期时间失败,则应首先实现查询并在内存中应用分组,这种方法会很昂贵。

注意:SqlFunctions.DateAdd接受字符串日期参数,可以查看官方documentation

编辑

如果你想在内存中应用解析日期和分组操作,你可以像这样重构你的代码;

db.JobProgress.Where(x => Job_Ids.Contains(x.JobId))
.Select(x => new {DateStr = x.Job.Date,Total = x.total}).ToList()
.GroupBy(x => new{ Year = Year_from_strDate(DateStr), Month = Month_From_strDate(DateStr)})
.Select(ln => new MyViewModel
{
   Year = ln.Key.Year,
   Month = ln.Key.Month,
   Amount = ln.Sum(r => r.Total)
}).ToList();

另外,我不知道Year_from_strDateMonth_From_strDate 方法是什么,但我假设您可以使用这些方法成功解析日期时间。

【讨论】:

  • 我以字符串格式存储的原因是我的应用程序支持多文化。如何始终以英文格式存储日期而不将其转换为字符串?我不想在这里使用SQLFunctions。还有其他选择吗?
  • 在这种情况下,您应该首先实现查询并在内存中应用解析。然后按月分组。
  • 你能帮我吗?我需要最小化代码。太丑了。
  • 我会试试的。 Year_from_strDateMonth_From_strDate 这些是从 string 日期获取年份和月份部分的函数。
猜你喜欢
  • 2013-04-05
  • 2018-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-25
  • 2016-03-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多