LINQ根据对象内列表中的属性选择对象

时间:2017-06-01 16:33:50

标签: linq linq-to-entities

我试图从一个对象列表中选择一个对象列表,这些对象列表中的另一个类型的对象基于该对象列表中的属性。

例如

class TypeA{
  string Name {get; set;}
  List<TypeB> ListOfTypeB {get; set;}
}

class TypeB{
  int Age {get; set;}
  bool Active {get; set;}
}

我有一个由数据库填充的Type A列表,我想查询TypeA列表并根据TypeB对象中的TypeB中的Active属性返回TypeA列表。

任何帮助都会很棒。

由于

2 个答案:

答案 0 :(得分:1)

具体取决于您实现过滤器逻辑的方式。如果你想找到类型B的列表,其类型B包含至少一个活动标志,那么你可以这样做。

listOfTypeA.Where(a => a.ListOfTypeB.Any(b => b.Active)).ToList();

答案 1 :(得分:1)

您写道:

  

我想查询TypeA列表并返回TypeA列表   TypeB中的Active属性。

这个规范有点不清楚。我假设您的意思是您希望所有TypeA个对象至少有一个TypeB个对象具有真值TypeB.Activity(或那些具有假值的对象)。

答案取决于您是要将查询作为Enumerable还是Queryable来执行。用语言:您首先要将对象放入本地内存然后执行查询(AsEnumerable)还是要让数据库执行查询(Asqueryable)然后只返回有效值结果是本地记忆。

<强> AsEnumerable

此方法效率不高,因为这意味着您在处理之前将完整的TypeA和TypeB表获取到本地内存。

但是你的查询很简单:

var AwithActivity = allTypeA
    .Where(a => a.ListOfTypeB.Any(b => b.Activity));

用语言说:

typeA元素的完整序列中,仅采用那些至少有一个typeA元素的ListOfTypeB元素,其属性为Activity的真值。

<强> AsQueryable已

如果您的数据库设置正确,您将有两个表。一个包含TypeA个项目的表和一个包含TypeB个项目的表。

TypeATypeB具有一对多的关系。每个TypeA都有零个或多个TypeB,而每个TypeB只属于一个TypeA

在您的数据库中,TypeATypeB都有一个主键。每个TypeB都会有TypeA所有的外键。

这是相当标准的数据库。它可以帮助您查询。使用这些定义,您的查询将被翻译为:

  

我想要所有TypeA对象,其中至少有一个TypeB对象具有此TypeA对象的外键,并且是活动的真值

查询将是:

var results = TypeATable            // groupjoin table TypeA with table TypeB
    .GroupJoin(TypeBTable,
      typeA => typeA.PrimaryKey,    // from every typeA use the primary key
      typeB => typeB.ForeignKey,    // from every typeB use the foreign key to the TypeA
      (a, allB) => new              // for every A with all matching typeB:
      {                             // create a new anonymous type
         A = a,                     // with the found A
         HasActivity = allB         // and a boolean that says if there was
            .Any(b => b.Activity),  // at least one B with a true Activity
      });

要让所有TypeA至少有一项活动:

var AWithActivity = results.Where(result => result.HasActivity)
   .Select(result => result.A);

要获得完全没有任何活动的所有TypeA:

var AwithoutActivity = result.Where(result => !result.HasActivity)
   .Select(result => result.A);

<强>加成 如果可能是typeA和typeB之间的关系不是一对多,而是多对多。在这种情况下,您将获取所有活动的typeB对象并查找具有此活动typeB对象的外键的所有typeA对象