从分组中获取最新记录并过滤状态

时间:2018-12-21 21:37:30

标签: c# linq

我有一个表列表,其中当按标识符(gtin分组时,我想基于createdDateTime获取该列表中的最新记录,而我只想从该列表中返回那个记录unassigned

如果我有这样的列表

GTIN | CreatedDate | status
123    12/19/2018    assigned
123    12/20/2018    unassigned
123    12/21/2018    closed

然后输入此代码

var ordered = query.GroupBy(o => o.gtin)
             .Select(o => o.OrderByDescending(p => p.createdDateTime).FirstOrDefault())
             .Where(o => o != null && o.status == "Unassigned");

运行时,我希望没有123的记录返回,因为123的最新创建日期是12/21,状态是closed而不是unassigned。 实际发生的是,我得到了123条记录,但它似乎未分配。 所以问题是我的select并没有像我想的那样带回最新记录的列表。

2 个答案:

答案 0 :(得分:1)

您写道:

  

我希望没有123的记录能够返回,因为123的最新创建日期是12/21,状态为关闭且未分配

确定吗?我尝试了以下代码:

enum Status { unassigned, assigned, closed };
class MyType
{
    public int Id { get; set; }
    public DateTime CreationDate { get; set; }
    public Status Status { get; set; }
}

static void Main(string[] args)
{
    IEnumerable<MyType> items = new List<MyType>
    {
        new MyType {Id = 123, CreationDate = new DateTime(2018, 12, 19), Status = Status.assigned},
        new MyType {Id = 123, CreationDate = new DateTime(2018, 12, 20), Status = Status.unassigned},
        new MyType {Id = 123, CreationDate = new DateTime(2018, 12, 21), Status = Status.closed},
    };

    var a = items.GroupBy(o => o.Id);
    var b = a.Select(o => o.OrderByDescending(p => p.CreationDate).FirstOrDefault());
    var c = b.Where(o => o != null && o.Status == Status.unassigned);
}

我的调试器告诉我:

- `a` is a sequence with one element: an `IGrouping<MyType>` with `Key` equal to 123, and a sequence of all three elements
- 'b' is also a sequence of one element, but now a sequence of `MyType`. This one element is the element with Date 21 dec 2018 and status Closed
- `c` is an empty sequence

这不是您想要和期望的吗?

答案 1 :(得分:0)

如果您要基于Unassigned返回最新的CreatedDate成员,则可以检查FirstOrDefault中的条件:

var firstOrder = list
                 .GroupBy(obj => obj.gtin)
                 .FirstOrDefault(obj => obj.Key == 123)
                 ?.OrderByDescending(obj => obj.createdDateTime)
                 .FirstOrDefault(o => o.status == "Unassigned");

但是,如果要返回的最新值为Unassigned,如果不返回的则返回null,则不能使用LINQ。您必须添加一个if条件:

var firstOrder = list
                 .GroupBy(obj => obj.gtin)
                 .FirstOrDefault(obj => obj.Key == 123)
                 ?.OrderByDescending(obj => obj.createdDateTime)
                 .FirstOrDefault();

if (firstOrder?.status == "Unassigned")
{
    //proceed with firstOrder
}