【问题标题】:Filter By Date in a GroupBy按 GroupBy 中的日期过滤
【发布时间】:2018-07-04 16:35:35
【问题描述】:

我需要一些关于使用 LINQ 查询按日期过滤的帮助。

所以,

这是我的班级:

public class MyList
    {
        public string Ent { get; set; }
        public string Con { get; set; }
        public int Count { get; set; }
        public double? Med { get; set; }
        public DateTime Data { get; set; }
    }

我的查询:

public IEnumerable<MyList> LoadData()
    {
        var ctx = new DbContext();

        var query = (from t in ctx.tblTimes.AsQueryable().Where(s => s.Included == true)
                     join av in ctx.tblPrincipal on t.AID equals av.AID
                     join c in ctx.tblCon on av.ConID equals c.ConID
                     join e in ctx.tblEnt on av.EntID equals e.EntID
                     group t by new
                     {
                         c.Name,
                         e.Entity
                     } into grp
                     select new MyList
                     {
                         Con = grp.Key.Name,
                         Ent = grp.Key.Entity,
                         Count = grp.Count(),
                         Med = grp.Average(s => s.Time),
                         Data = grp.Select(s => s.tblPrincipal.Data).FirstOrDefault()
                     });
        if (CmbCon.SelectedItem != null)
        {
            var selected = (tblCon)CmbCon.SelectedItem;
            query = query.Where(s => s.Name == selected.Name);
        }
        if (CmbEnt.SelectedItem != null)
        {
            var selected = (tblEnt)CmbEnt.SelectedItem;
            query = query.Where(s => s.Entity == selected.Entity);
        }
        if(DataFrom.Checked && DataTo.Checked)
        {
            DateTime inicio = DataAgendFrom.Value;
            DateTime fim = DataAgendTo.Value;
            query = query.Where(s => s.Data >= inicio && s.Data <= fim);
        }
        return query.ToList();
    }

我的 OnLoad 事件:

private void Form_OnLoad(object sender, EventArgs e)
    {
        data.DataSource = LoadData();
        data.Columns["Data"].Visible = false;
    }

所以,如果我按 2 ComboBox 过滤,过滤器工作正常并且结果显示正确,但如果我按日期过滤,如果我给出了我的全部,就像没有过滤器一样...

来自 Inicio 和 Fim Date 的一些图片...

Inicio

电影

在我的 MSSQL 数据库中,我有 2 条记录,其日期如下图所示...上面的日期范围完全适合我的数据库记录中的 1 条。

但是,当我在 Image(Inicio 和 Fim)中应用日期时,我得到 2 条记录(计数 = 2,平均值 = 2 条记录的平均值)。 有什么想法吗?

编辑:经过一些测试,我发现对于上面的范围日期,查询返回数据库中的所有记录时,只应返回一条适合范围的记录,但有另一个范围(Inicio 2018-06 -19 00:00:00; Fim 2018-06-19 23:59:59),根本没有返回结果,这是错误的,因为数据库中的第二条记录在这个范围内!看不懂,但我怀疑问题出在这段代码上:

Data = grp.Select(s => s.tblPrincipal.Data).FirstOrDefault()

如果第一条记录适合日期范围,则返回所有记录,如果第一条记录不适合范围,则不返回任何结果!

谢谢

【问题讨论】:

  • “如果我按日期过滤,如果我全力以赴,就像没有过滤器一样”是什么意思?什么是“日期”?
  • 谁是DataFromDataToDataFrom.Value 返回字符串还是日期时间?如果它是一个字符串,你可能应该解析为 DateTime
  • 是的,就像没有应用过滤器一样!对于日期,我的意思是日期范围 DataFrom 和 DataTo。这 2 个是我在表单中的 2 个 DatePicker,用于从 DataFrom 到 DataTo 范围过滤日期。
  • DataFrom 和 DataTo 是 Form 中的 2 个 DateTimePickers,它应该过滤要在数据属性中应用的日期范围(s => s.Data >= DataFrom... 我已经更改了我的查询DataFrom.Checked 和 DataTo.Checked 转换为 Date...
  • 你能显示 DataFrom 和 DataTo 的值吗?

标签: c# linq


【解决方案1】:

我认为您只需要提前应用过滤器即可影响聚合值,如下所示:

public IEnumerable<MyList> LoadData()
{
    var ctx = new DbContext();

    var set = ctx.tblTimes.AsQueryable();


   if(DataFrom.Checked && DataTo.Checked)
   {
       DateTime inicio = DataAgendFrom.Value;
       DateTime fim = DataAgendTo.Value;
       set = set.Where(s => s.Data >= inicio && s.Data <= fim);
    }

    var query = (from t in set.Where(s => s.Included == true)
                 join av in ctx.tblPrincipal on t.AID equals av.AID
                 join c in ctx.tblCon on av.ConID equals c.ConID
                 join e in ctx.tblEnt on av.EntID equals e.EntID
                 group t by new
                 {
                     c.Name,
                     e.Entity
                 } into grp
                 select new MyList
                 {
                     Con = grp.Key.Name,
                     Ent = grp.Key.Entity,
                     Count = grp.Count(),
                     Med = grp.Average(s => s.Time),
                     Data = grp.Select(s => s.tblPrincipal.Data).FirstOrDefault()
                 });
    if (CmbCon.SelectedItem != null)
    {
        var selected = (tblCon)CmbCon.SelectedItem;
        query = query.Where(s => s.Name == selected.Name);
    }
    if (CmbEnt.SelectedItem != null)
    {
        var selected = (tblEnt)CmbEnt.SelectedItem;
        query = query.Where(s => s.Entity == selected.Entity);
    }

    return query.ToList();
}

【讨论】:

  • 谢谢。但是您的建议仍然没有日期过滤器。
  • @CarlosFerreira 你确定吗?您查询中的错误是您只过滤grp 中的第一个日期,这意味着grp 可能包含指定时间间隔之外的日期。此答案中的查询不应返回任何这些,因为数据在分组之前已被过滤。无论如何,这是要走的路。
【解决方案2】:

在漫长的工作日之后,我可能会说一些愚蠢的话,但我发现您的数据库元素都非常适合 iniciofim 的范围。

DataTo 和 DateFrom 以及您的数据集具有相同的日、月和年。您的数据集的小时数介于 00(数据来自)和 23(数据至)之间。

另外,我可能假设您的数据库和代码中有不同的格式。 例如:

Database: mm/dd/yyyy, 24hours
Code: dd/mm/yyyy, 12hours

这也可能出现问题。 希望能帮助到你。如果有不清楚的地方,请不要犹豫与我联系。

【讨论】:

  • 日子不同- 9 和 19
  • @Dmitry Pavliv,非常辛苦的一天,抱歉。格式呢?成员查询是否返回两个元素?或者你稍后会得到两个元素?
  • 数据库和代码上的日期格式类似...格式yyyy-MM-dd HH:mm:ss
  • 我几乎可以肯定问题出在这里! Data = grp.Select(s =&gt; s.tblPrincipal.Data).FirstOrDefault()。我在这里想要实现的是从数据库中获取日期属性,以便我可以在查询中进行比较!
猜你喜欢
  • 1970-01-01
  • 2023-03-16
  • 2022-11-04
  • 2021-07-13
  • 2013-11-25
  • 1970-01-01
  • 2018-09-08
  • 2019-03-01
  • 2016-01-10
相关资源
最近更新 更多