LINQ Group如果对象具有x个属性,则在每个组上选择

时间:2013-08-01 20:55:57

标签: c# linq

我对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集合分组为PersonSenderBuildingSender当这些实例具有{{1}时实例本身。

然后我想对每组Post个对象执行一个select查询,这样我就可以返回使用每个{在select语句中创建的另一个对象Collection的{​​{1}}集合。 {1}}的属性。 这里的关键是我需要对返回的每个组执行单独的select语句

这是我到目前为止实际查询的内容

IEnumerable

但是我很确定这不会编译,它不会为我提供我需要的多个select语句。

GroupBy是正确的方法吗?它甚至可能吗?

更新: Per @Hogan我已经能够将工作解决方案整合在一起了。让我试着澄清我想要做的事情,但我原来的问题不是很清楚......

此代码是类Package的一部分。我的应用程序中的Controller可以调用此类中的每个方法,以请求一组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())); 接受几种类型的PackageFactory对象作为参数,并将与Package对象所具有的关系相关联的内容包装到一个接口中,显示应用程序上的信息的任何其他控制器都可以读取该接口。 TLDR Package是一个美化的适配器模式设计对象。

IEntity中的每个方法都有查询IEntity存储库,找到具有正确属性集的相关Package对象,然后传递对象子集(即在将整个PackageFactory对象集合返回到控制器之前,要包装的新Communication实例的Communication对象的属性,以便它们可以在页面上呈现。

对于我正在为此问题撰写的方法,用户Communication包含Package个对象的集合,其中每个Package来自m个对象(或者针对用户Communication的{​​{1}}或Communication)。我的查询是尝试将IEntity个对象分成两组,其中一组包含PersonSender存在BuildingSenderm存在的所有Communication。这样我的方法就知道哪个组被传递给它们各自的Communication类型。

我尝试使用GroupBy的逻辑是我宁愿使查询尽可能通用,这样我以后可以扩展到更多集合和/或通过不必调用许多单独的查询来提高方法的性能加入他们。但是,似乎不可能在每个组上指定不同的选择查询。

@Hogan的答案接近我希望能够做到的。

Hogan的回答

PeronSender

修改后的答案

这是有效的:

BuildingSender

不完全一样 - 昨天我写这个问题时,我的脑袋有点模糊。

1 个答案:

答案 0 :(得分:2)

我认为关键是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}));