LINQ分组依据如果一个对象有x个属性,则在每个组上进行选择
本文关键字:选择 行选 属性 如果 一个对象 LINQ | 更新日期: 2023-09-27 18:26:09
我对LINQ有一些经验,但编写这个查询有点力不从心。
对不起,我的伪代码。。。
class Person{
Collection<Communications> {get;set}
}
class Communication{
Collection<PersonSender> {get;set;}
Collection<BuildingSender> {get;set;}
}
class PersonSender{
Collection<Posts> {get;set}
}
class BuildingSender{
Collection<Posts> {get;set}
}
我想要完成的任务:当Communication
集合本身具有Post
实例时,根据该集合是否包含PersonSender
或BuildingSender
的实例对其进行分组。
然后,我想对每组Collection
对象执行一个select查询,这样我就可以返回另一个对象Package
的IEnumerable
集合,该集合是在select语句中使用每个Collection
的属性创建的这里的关键是,我需要对返回的每个组执行单独的选择语句
这是我目前实际查询的结果
m.Communications.GroupBy(x =>
new {fromMember = (x.PersonSender.Any() && x.Posts.Any()),
fromBuilding = (x.BuildingSender.Any() && x.Posts.Any())})
.Select(u => new Package(u.PersonSender.First().Member,u.Posts.First()));
然而,我确信这不会编译,也不会为我提供所需的多选语句。
GroupBy是解决这个问题的正确方法吗?这可能吗?
更新:Per@Hogan我已经能够破解一个工作解决方案。让我试着弄清楚我想做什么,尽管我最初的问题不是很清楚。。。
此代码是类PackageFactory
的一部分。这个类中的每个方法都可以由我的应用程序中的控制器调用,请求一组Package
对象。Package
接受几种类型的IEntity
对象作为参数,并将与IEntity
对象具有的关系相关联的内容封装到任何其他在我的应用程序上显示信息的控制器都可以读取的接口中。TLDR Package
是一个荣耀的Adapter模式设计对象。
PackageFactory
中的每种方法都要查询Communication
存储库,找到具有正确属性集的相关Communication
对象,然后将对象子集(即Communication
对象的属性)传递给要包装的新Package
实例,然后将整个Package
对象集返回给控制器,以便在页面上呈现它们。
在我为这个问题编写的方法的情况下,用户m
具有Communication
对象的集合,其中每个Communication
来自指向用户m
的IEntity
对象(PersonSender
或BuildingSender
)。我的查询试图将Communication
对象分离为两个集合,其中一个包含所有Communication
,其中PeronSender
存在,另一个包含BuildingSender
存在。通过这种方式,我的方法知道哪个组被传递到它们各自的Package
类型。
我尝试使用GroupBy的逻辑是,我宁愿让查询尽可能通用,这样我以后就可以扩展到更多的集。AND/OR通过不必调用许多单独的查询然后将它们全部联接来提高方法的性能。然而,似乎不可能在每个组上指定不同的选择查询。
@霍根的回答接近我想要做的。
霍根的答案
var result =
m.comm.SelectMany(x => x.person).Where(x => x.posts.Any()).Select(new () { x.name, x.posts})
.Union(m.comm.SelectMany(x=> x.building).Where(x => x.posts.Any()).Select(new () {x.name, x.posts}));
修改的答案
这就是工作原理:
return m.Communications.Where(x => x.SendingPerson.Any() && x.Posts.Any()).Select(u =>
new PostPackage(u.SendingPerson.First().Member,m,u.Posts.First()))
.Union(m.Communications.Where(x=> x.BuildingSender.Any() && x.Posts.Any()).Select(u =>
new PostPackage(u.BuildingSender.First().Building,m,u.Posts.First())));
不完全一样——昨天我写这个问题的时候脑子有点模糊。
我认为关键是SelectMany而不是GroupBy——这将"压平"子列表。如下所示:
带
class Person{
Collection<Communications> comm {get; set;}
}
class Communication{
Collection<PersonSender> person {get; set;}
Collection<BuildingSender> building {get; set;}
}
class PersonSender{
string name {get; set; }
Collection<Posts> posts {get; set;}
}
class BuildingSender{
string name {get; set; }
Collection<Posts> posts {get; set;}
}
假定m是一个人:
var result =
m.comm.SelectMany(x => x.person).Where(x => x.posts.Any()).Select(new () { x.name, x.posts})
.Union(m.comm.SelectMany(x=> x.building).Where(x => x.posts.Any()).Select(new () {x.name, x.posts}));