你写道:
我想查询 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 项目的表。
TypeA 与TypeB 具有一对多关系。每个TypeA 有零个或多个TypeB,每个TypeB 恰好属于一个TypeA。
在您的数据库中,TypeA 和 TypeB 都有一个主键。每个TypeB 都有一个指向它所属的TypeA 的外键。
这是相当标准的数据库。它可以帮助您进行查询。使用这些定义,您的查询将被翻译成:
我想要所有 TypeA 对象,其中至少有一个 TypeB 对象具有此 TypeA 对象的外键和 Activity 的真值
查询将是:
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 对象