基本上我想要做的是让父母按父类进行分组,其中他们的Child.type具有状态' y'由child.Date命令
作为一个例子,我创建了这些类:
public class Collection
{
public IEnumerable<Parent> Parents { get; set; }
public int Id { get; set; }
}
public class Parent
{
public int Id { get; set; }
public Type type { get; set; }
public IEnumerable<Child> Children { get; set; }
}
public class Child
{
public int Id { get; set; }
public Status Status { get; set; }
public DateTime Date { get; set; }
}
public enum Type
{
a,
b
}
public enum Status
{
x,
y
}
我想要的是每个类型的父母列表,其中儿童的日期值最高。
为了得到这个例子,我添加了一些测试数据:
Collection collection= new Collection
{
Id = 1,
Parents = new List<Parent>
{
new Parent
{
Id= 1,
type = Type.a,
Children = new List<Child>
{
new Child
{
Id = 1,
Status = Status.y,
Date = DateTime.Now.AddDays(-1)
},
new Child
{
Id = 2,
Status = Status.x,
Date = DateTime.Now.AddDays(-1)
}
}
},
new Parent
{
Id= 2,
type = Type.b,
Children = new List<Child>
{
new Child
{
Id = 3,
Status = Status.y,
Date = DateTime.Now.AddDays(-2)
},
new Child
{
Id = 4,
Status = Status.x,
Date = DateTime.Now.AddDays(-2)
}
}
},
new Parent
{
Id= 3,
type = Type.a,
Children = new List<Child>
{
new Child
{
Id = 5,
Status = Status.y,
Date = DateTime.Now.AddDays(-3)
}
}
},
new Parent
{
Id= 4,
type = Type.b,
Children = new List<Child>
{
new Child
{
Id = 6,
Status = Status.y,
Date = DateTime.Now.AddDays(-3)
},
new Child
{
Id = 7,
Status = Status.y,
Date = DateTime.Now.AddDays(-4)
},
new Child
{
Id = 8,
Status = Status.x,
Date = DateTime.Now.AddDays(-4)
}
}
},
}
};
select的结果应该是包含2个Parent的List。每种类型一个(a和b)。这两个仍然包含所有的Child对象。
这有什么简单的解决方案吗?
我尝试过类似的事情:
List<Parent> test = collection.Parents
.GroupBy(m => m.type)
.Select(
m => m.OrderByDescending(
mm => mm.Children.Select(
r => r).OrderByDescending(
r => r.Date)).FirstOrDefault()).ToList();
但那并没有很好地结束。
===== UPDATE =====
感谢Enigmativity的例子,这个问题已经解决了。我对linq查询稍作修改,因为我使用的原始内容是由Entity Framework(6)提供的。这对我来说意味着所选的Parent对象不包含任何Children,因此我必须选择一个新的对象类型(因为我们不能实例化Entity Framework模型提供的类型的新对象)。我的父母也在另一个IEnumerable中,所以我不得不在父母身上使用SelectMany。
这导致了这样的事情:(虽然这不会与测试类一起工作)
var result =
collection
.SelectMany(c => c.Parents)
.GroupBy(p => p.type)
.SelectMany(gps =>
gps
.SelectMany(
gp => gp.Children.Where(c => c.Status == Status.y),
(gp, c) => new { gp, c })
.OrderByDescending(gpc => gpc.c.Date)
.Take(1)
.Select(gpc => new ParentData {Id = gpc.gp.Id, Children= gpc.gp.Children}))
.ToList();
答案 0 :(得分:1)
如果我已正确理解您的要求,您希望按类型对所有父母进行分组,然后根据该组中所有孩子中具有最高日期的孩子的父母,选择每组中的一个父母。< / p>
以下是我提出的建议:
var result =
collection
.Parents
.GroupBy(p => p.type)
.SelectMany(gps =>
gps
.SelectMany(
gp => gp.Children.Where(c => c.Status == Status.y),
(gp, c) => new { gp, c })
.OrderByDescending(gpc => gpc.c.Date)
.Take(1)
.Select(gpc => gpc.gp))
.ToList();
这让我:
答案 1 :(得分:0)
当父母是应用查询/投射的父母时,儿童无法真正被过滤,下令等。
你必须要么:
IGrouping
,其中父项是键,排序的子项是值)Sort()
就我个人而言,我认为仅将您需要的数据投影到简化表示中更容易,而不是试图将层次结构一直保持下来。
答案 2 :(得分:0)
我对这个问题的理解是你需要创建一个按类型分组的父母列表,并聚合所有父类型的状态为y的子项。
为此,请注意您不能按父类型折叠列表并保留父结构(意味着Id也必须折叠,我只是采用了第一个值,它是由...你选择不同)。否则,这应该是您正在寻找的解决方案:
var result = collection.Parents.GroupBy(c => c.type)
.Select(g => new Parent
{
type = g.Key,
Id = g.Select(p => p.Id).FirstOrDefault(),
Children = g.SelectMany(p => p.Children
.Where(c => c.Status == Status.y)
.OrderByDescending(c => c.Date)).ToList()
}).ToList();