【问题标题】:Return items between date and only if created before another item was deleted返回日期之间的项目,并且仅在删除另一个项目之前创建
【发布时间】:2014-02-19 18:48:49
【问题描述】:

假设我有一个包含创建和删除日期时间的项目列表:

  ITEM,   CREATED, DELETED
item 1, 1/1/1999, 1/14/2014
item 2, 1/1/1999, 1/17/2014
item 3, 1/15/2014, NULL
item 4, 1/16/2014, NULL

我需要一个包含最终结果的列表,所以

项目 3 取消项目 1,因为它是在项目 1 被删除之后创建的,但项目 4 不会取消项目 2,因为它是在项目 2 被删除之前创建的。

所以最终结果应该是一个列表

第 2 项、第 3 项、第 4 项

我现在的代码如下

                int year = DateTime.Now.Year;
                DateTime sdate = new DateTime(year, DateTime.Now.Month - 1, 1);
                DateTime edate = new DateTime(year, DateTime.Now.Month, 1);

                var qry = Emails.collection.Where(t => 
                    t.deletedon.HasValue ?
                    t.deletedon.Value >= sdate :
                    t.createdon.Value < edate
                    ).ToArray()

但此代码包含第 1 项。 因此它包括在结束日期之前创建的所有未删除的项目,除非在开始日期之后删除。

但是,如果删除了一个项目并创建了一个新项目,那么列表将同时包含这两个项目。但我基本上需要用创建的邮件替换已删除的邮件,因此最终结果计数总计一次创建和活动的最大电子邮件数..

Emails.Item[] created = Emails.collection.Where(t => t.createdon.Value >= sdate && t.createdon.Value < edate).ToArray();
Emails.Item[] deleted = Emails.collection.Where(t => t.deletedon.HasValue && (t.deletedon.Value >= sdate && t.deletedon.Value < edate)).ToArray();

Emails.Item[] exceptions = deleted.Where(t => created.FirstOrDefault(c => c.createdon.Value >= t.createdon.Value)).ToArray(); ???

【问题讨论】:

  • 我认为使用类似方法将集合/复制值简单地修改为另一个更容易;而不是尝试在哪里进行 linq,因为对于您在哪里工作,您需要将其自身加入集合以检查您正在查看的日期如何与集合中的所有其他项目匹配。这更容易在正常的循环逻辑中处理。
  • 是的,我想我在上面的 linq 中需要一个例外。我正在尝试在另一个列表中获取例外。
  • 我猜你的问题源于没有物品的标识符!

标签: c# linq logical-operators


【解决方案1】:

您的查询的问题在于,正如您所描述的,取消某个项目取决于与另一个项目的比较,而您的 Where 只是检查每个项目本身的条件。

假设我很好地理解了你的问题:

  • 您需要一份所有未删除项目以及已删除但未取消项目的列表。
  • 如果在删除后创建了另一个项目,则该项目被视为已取消

如果是这种情况,我会先检索未删除的项目,然后分别检索已删除的项目。下一步将使用未删除项目的创建日期过滤已删除项目。

这样做的一种简单方法是按创建日期对未删除的项目进行排序并获取最早的项目并使用它来丢弃删除日期早于该日期的所有已删除项目。

最后一步:合并两个列表。

【讨论】:

  • 是的,这是正确的方向..这基本上是我得出的结论..仍然很难获得例外列表..我会尝试理解你描述的过程..在某种程度上,您的最终描述听起来不正确..正确的方法似乎是我需要获取在另一个项目被删除后创建的第一个项目.. 嗯有点混乱
【解决方案2】:

这是一个丑陋但有效的版本..

                int year = DateTime.Now.Year;
                DateTime sdate = new DateTime(year, DateTime.Now.Month - 1, 1);
                DateTime edate = new DateTime(year, DateTime.Now.Month, 1);

               Emails.Item[] created = Emails.collection.Where(t => t.createdon.HasValue && (t.createdon.Value >= sdate && t.createdon.Value < edate)).OrderByDescending(y => y.createdon).ToArray();
                List<Emails.Item> deleted = Emails.collection.Where(t => t.deletedon.HasValue && (t.deletedon.Value >= sdate && t.deletedon.Value < edate)).OrderByDescending(y => y.deletedon).ToList();
                List<Emails.Item> ex = new List<Emails.Item>();
                foreach (Emails.Item t in created)
                {
                    Emails.Item d = deleted.FirstOrDefault(y => y.deletedon.Value >= t.createdon.Value);
                    if (d != null && t.createdon.Value <= d.deletedon.Value)
                    {
                        deleted.Remove(d);
                        ex.Add(t);
                    }
                }

                //System.Windows.MessageBox.Show(created.Count().ToString() + " / " + deleted.Count().ToString() + " / " + ex.Count().ToString());

                var qry = Emails.collection.Where(t => 
                    t.deletedon.HasValue ?
                    t.deletedon.Value >= sdate :
                    t.createdon.Value < edate
                    ).Except(ex).ToArray()
                    .OrderBy(t => t.lastname).OrderBy(t => t.firstname).GroupBy(x => x.company, (key, group) => new { Company = key, Items = group });

有谁知道压缩这一切的方法吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-31
    • 2018-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多