使用SelectMany()或使用LINQ(点语法)匹配两个序列的元素

时间:2012-02-23 19:54:02

标签: c# asp.net entity-framework linq

我需要选择Id属性包含在第二组中的集合中的所有元素。可以使用“SelectMany()”来实现这一目标吗?这类匹配问题的最有效/最佳解决方案是什么。

示例: 通过加入实体集选择给定ReportId的所有DateRangeIds。

  • 报告 {ReportId,ReportName}
  • ReportDateRanges {DateRangeId,ReportId,ReportDateRangeId}
  • DateRanges {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专家,请随时批评此代码并提供任何建议。谢谢你的帮助!

4 个答案:

答案 0 :(得分:1)

好吧,你可以使用Enumerable.Intersect(Of TSource) Method (IEnumerable(Of TSource), IEnumerable(Of TSource), 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

使用link中指定的重载,您可以为自定义对象指定EqualityComparer,以便查找两个枚举的交集。

希望这有帮助。

答案 1 :(得分:1)

我认为您的代码简单易读,但有些东西并不好:

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但你不需要这个。

答案 2 :(得分:1)

您可以加入馆藏。 如果您拥有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);

答案 3 :(得分:0)

这是一种方法:

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);