使用SelectMany()或使用LINQ(点语法)匹配两个序列的元素
本文关键字:两个 元素 语法 SelectMany LINQ 使用 | 更新日期: 2023-09-27 18:25:32
我需要从一个集合中选择所有元素,该集合的Id属性包含在第二个集合中。可以使用"SelectMany()"来实现这一点吗?对于这类匹配问题,什么是最有效/最好的解决方案。
示例:通过联接实体集的方式为给定ReportId选择所有DateRangeId。
集合:
- 报告{ReportId,ReportName}
- ReportDateRanges{DateRangeId,ReportId,ReportDateRangeId}
- 日期范围{DateRangeId,DateRangeName}
这是我的解决方案代码。我不确定这是否是正确的方法,但这确实解决了我所描述的问题:
var report = Reports.Take(1).FirstOrDefault();
int reportId = Convert.ToInt32(report.Id);
var dateRangeIds = ReportDateRanges.Where(rdr => rdr.ReportId == reportId).OrderBy(it => it.DateRangeId).Select(it => it.DateRangeId);
var dateRanges = DateRanges.Where(dateRange => dateRangeIds.Contains(dateRange.Id));
LINQ专家,请随时评论此代码并提供任何建议。谢谢你的帮助!
好吧,你可以使用Enumerable.Intersect(Of-TSource)方法(IEnumerable(Of-TSource),IEnumeraable(Of-TSources),IEqualityComparer(Of TSource))
例如:
var list1 = new List<int> {1,2,3,4,5,6,7,8};
var list2 = new List<int> {9,10,11,12,13,4,5};
list1.Intersect(list2);
结果
4,5
使用链接中指定的重载,您可以为自定义对象指定EqualityComparer
,以便找到两个枚举的交集。
希望这能有所帮助。
我认为您的代码简单可读,但也有一些不好的地方:
var report = Reports.Take(1).FirstOrDefault();
你可以写:
var report = Reports.FirstOrDefault();
在这一行:
var dateRangeIds = ReportDateRanges.Where(rdr => rdr.ReportId == reportId)
.OrderBy(it => it.DateRangeId)
.Select(it => it.DateRangeId);
你使用了orderby,但你不需要这个。
您可以加入集合。假设您有reportId
,则可以发出此查询。
Reports
.Where(report => report.ReportId == reportId)
.Join(ReportDateRanges,
report => report.ReportId,
rdr => rdr.ReportId,
(report, reportDateRange) => reportDateRange)
.Join(DateRanges,
rdr => rdr.DateRangeId,
dateRange => dateRange.DateRangeId,
(reportDateRange, dateRange) => dateRange);
这里有一种方法:
IEnumerable<SomeTypeWithAnIDProperty> sourceSequence = //whatever
IEnumerable<TypeOfTheIDProperty> ids = //whatever
var selectedItems =
from sourceObject in sourceSequence
join id in ids
on sourceObject.ID equals id
select sourceObject;
或者,使用您的示例
var dateRangeIds = ReportDateRanges
.Where(rdr => rdr.ReportId == reportId)
.OrderBy(it => it.DateRangeId)
.Select(it => it.DateRangeId);
var dateRanges = DateRanges.Join(dateRangeIds, dateRange => dateRange.Id, id => id, (dateRange, id) => dateRange);