【问题标题】:LINQ, select with only the first element of child itemLINQ,仅选择子项的第一个元素
【发布时间】:2011-08-02 19:27:18
【问题描述】:

使用 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

【问题讨论】:

  • 所以你一直都有正确的实现?还是您想要报告但 PerformanceMetric 应该只包含第一个元素?
  • 是 Report.PerformanceMetrics 仅包含 1 或 0 个元素的报告。数据库中的报告可能有 1000 条 PerformanceMetric 记录...
  • 好的,让我直截了当,您想要报告,但您想要修改报告以使 PerformanceMetric 仅包含 0/1 元素?
  • 看看我下面的内容,看看它是否更适合您的需求。
  • 正如他们在下面写的,你应该单独拿出PerformanceMetric。

标签: c# linq linq-to-sql


【解决方案1】:

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

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

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

更新:根据问题中的更新,您想要一些不同的东西。您需要报告,但只有 1 个性能指标。这涉及改变原始报告(不确定所有成员),这可能有点麻烦,因为您不想在 LINQ 中操作原始数据。

所以你有两个选择:

  1. 您可以创建一个新的 Report 实例并复制所有属性和一个指标。
  2. 您可以将报告和属性一起创建一个匿名类型。

我可能更喜欢 #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();

【讨论】:

  • 只是一个关于否决票的建议,如果您要投反对票,最好附上关于原因的评论,以便作者了解问题所在。
【解决方案2】:

你在寻找这样的东西吗?

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

【讨论】:

    猜你喜欢
    • 2015-06-07
    • 2021-08-24
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-17
    相关资源
    最近更新 更多