我有一些使用 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
分组是否包含 PersonSender
实例的集合或BuildingSender
当这些实例有 Post
时实例本身。
然后我想对Collection
的每组执行选择查询对象,这样我就可以返回 IEnumerable
另一个对象的集合Package
使用每个 Collection
在 select 语句中创建的的属性。 这里的关键是我需要对返回的每个组执行单独的选择语句
这是迄今为止我得到的实际查询
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 是解决这个问题的正确方法吗?这可能吗?
更新:根据@Hogan,我已经能够拼凑出一个工作解决方案。让我试着弄清楚我想要做什么,我原来的问题不是很清楚......
此代码是类 PackageFactory
的一部分。此类中的每个方法都可以由我的应用程序中的 Controller 调用,要求一组 Package
对象。 Package
接受多种类型的 IEntity
对象作为参数并包装与 IEntity
关系关联的内容。对象已进入一个接口(interface),任何其他在我的应用程序上显示信息的 Controller 都可以读取该接口(interface)。总而言之 Package
是一个美化的适配器模式设计对象。
PackageFactory
中的每个方法负责查询Communication
存储库,查找相关Communication
具有正确属性集的对象,然后将对象子集(即 Communication
对象的属性)传递给新的 Package
返回整组 Package
之前要包装的实例对象到 Controller ,以便它们可以呈现在页面上。
就我为这个问题编写的方法而言,用户 m
收藏了Communication
每个 Communication
的对象来自IEntity
指向用户 PersonSender
的对象( BuildingSender
或 m
) 。我的查询是试图隔离 Communication
对象分成两组,其中一组包含所有 Communication
哪里PeronSender
存在且其中 BuildingSender
存在。这样我的方法就知道哪个组被传递给各自的 Package
类型。
我尝试使用 GroupBy 的逻辑是,我宁愿使查询尽可能通用,以便以后可以扩展到更多集和/或通过不必调用许多单独的查询来提高方法的性能,然后加入他们所有人。然而,似乎不可能在每个组上指定不同的选择查询。
@Hogan 的答案接近我想要做的事情。
霍根的回答
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}));
关于c# - LINQ Group By 如果一个对象有 x 个属性,则在每个组上进行选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18004387/