繁体   English   中英

LINQ 分组过滤特定记录

[英]LINQ group by and filter particular record

public class Data
{
    public int Id { get; set; }
    public string Status { set; get; }
}

List<Data> dta = new List<Data>
{
    new Data { Id =1 , Status ="Open"},
    new Data { Id =1 , Status ="Pending"},
    new Data { Id =2 , Status ="Open"},
    new Data { Id =3 , Status ="Open"},
};

到目前为止尝试过

var outPutData = dta.GroupBy(x => x.Id).Select(g => g.FirstOrDefault(x => x.Status == "Pending"));

我在outPutData集合中得到如下结果

Id =1 , Status ="Pending"
null
null

outPutData 集合中的预期结果

Id =1 , Status ="Pending"
Id =2 , Status ="Open"
Id =3 , Status ="Open"

您当前的 Id=2 和 Id=3 对象没有待处理状态; 没有这样的对象,所以 FirstOrDefault 的结果是“默认”,即 null - FirstOrDefault 的意思是“给我第一个 object 可能有很多,如果这个条件为真,或者如果没有匹配的 ZA8CFDE6331BD49EB2AC96F8 给我默认值类型(通常为空)”

也许你想要类似的东西

var outPutData = dta.GroupBy(x => x.Id).Select(g => g.OrderBy(x => x.Status == "Pending"?0:1).First());

这将对待处理的对象进行排名(排序),以便它们位于任何打开的对象之前,因此将首先被拾取,但重要的是它不会丢弃任何东西,因此打开的对象仍然可用。

如果你只想要组的第一项,你可以使用这个:

var outPutData = dta
.GroupBy(x => x.Id)
.Select(g =>
{
    return g.FirstOrDefault(x => x.Status == "Pending") ?? g.FirstOrDefault();
});

这意味着如果当前组包含状态为 Pending 的项目,它将返回该项目。 如果它不包含状态为 Pending 的项目, g.FirstOrDefault(x => x.Status == "Pending")将为 null。 所以g.FirstOrDefault() (组的第一项,或者 null 如果没有)将被返回。

尝试这样做

var outPutData = dta
                .GroupBy(x => x.Id)
                .Select(g =>
                {
                    Data res;
                    var pending = g.FirstOrDefault(x => x.Status == "Pending");
                    if (pending != null)
                    {
                        res = pending;
                    }
                    else
                    {
                        var other = g.FirstOrDefault();
                        res = other;
                    }
                    return res;
                });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM