LINQ,只选择子项的第一个元素

时间:2011-08-02 19:27:18

标签: c# linq linq-to-sql

使用LINQ,如何进行选择并仅返回第一个关联子项?

我有:

[table: Report]
    GeneratedDate
    PerformanceMetric  1 -----> N [table PerformanceMetric]
    Bios                              Timestamp
    ...                               X
                                      Y 
                                      ..... (there is a good dozen other fields)

目前,我这样做:

 Report = _ctx.Reports.SingleorDefault(rpt => rpt.bios == mySerial);

这将返回与所有PerformanceMetric相关联的报表。我想只返回第一次出现的PerformanceMetric。

LINQ是否提供了这样做的内置方式?

编辑:事实上,我正在寻找报告,但PerformanceMetric应该只包含第一个元素。 (Report.PerformanceMetrics.Count< = 1) sry不清楚..

2 个答案:

答案 0 :(得分:3)

很难根据您的XML确切地说出完整的结构,但是类似于:

var firstMetric = _ctx.Reports
    .Where(rpt => rpt.bios == mySerial)
    .Select(rpt => rpt.PerformanceMetrics) // assuming name here...
    .FirstOrDefault();

如果where子句没有找到任何报告或没有性能指标,则返回匹配mySerial的报告的第一个性能指标,或默认值(类为null)。

更新:根据问题中的更新,您需要不同的内容。您想要报告,但只有一个性能指标。这包括改变原始报告(不确定所有成员),这可能有点毛茸茸,因为你不想在LINQ中操纵原始数据。

所以你有两个选择:

  1. 您可以创建一个新的Report实例并复制所有属性,只需一个指标。
  2. 您可以创建包含报告和属性的匿名类型。
  3. 我可能更喜欢#2,因为返回修改后的报告可能会令人困惑。所以你可以这样做:

    var firstMetric = _ctx.Reports
        .Where(rpt => rpt.bios == mySerial)
        .Select(new { Report = rpt, Metric = rpt.PerformanceMetrics.FirstOrDefault() })
        .FirstOrDefault();
    

    这将扫描报告中的bios == mySerial,创建一个新的匿名类型,报告成员==原始报告,公制成员==报告列表中的第一个指标。

    如果不存在任何指标但报告存在,您将获得一个匿名类型,其中Report =您的报告,Metric = null。如果没有匹配条件的报告,则返回null。

    如果你真的想要#1,你可以这样做:

    var firstMetric = _ctx.Reports
        .Where(rpt => rpt.bios == mySerial)
        .Select(new Report 
            { 
                PerformanceMetrics = rpt.PerformanceMetrics.Take(1),
                // copy all other Report fields here...
            })
        .FirstOrDefault();
    

答案 1 :(得分:2)

你在找这样的东西吗?

var reportMetric = (from r in _ctx.Reports select r.PerformanceMetric where r.Bios == mySerial).FirstOrDefault();