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

3

使用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) 抱歉没有表达清楚..


所以你一直都有正确的实现吗?或者你想要报告,但是“PerformanceMetric”应该只包含第一个元素? - Tomas Jansson
是的,报告中包含 Report.PerformanceMetrics,其中仅包含1个或0个元素。在数据库中,与报告相关联的 PerformanceMetric 记录可能有数千条... - Apoulet
好的,让我明确一下,您想要报告,但您希望修改报告,使PerformanceMetric仅包含0/1元素? - James Michael Hare
看看我下面的内容,看看它是否更适合您的需求。 - James Michael Hare
正如他们所写的,您应该将 PerformanceMetric 单独取出。 - Tomas Jansson
2个回答

4

根据您的XML,很难准确地确定完整结构,但可能类似于:

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

这将返回与我的串行匹配的报告的第一个性能指标,或者如果where子句没有找到任何报告或没有性能指标存在,则为默认值(类的 null)。
更新:根据问题中的更新,您想要不同的东西。 您想要报告,但只有其中1个性能指标。这涉及到改变原始报告(不确定所有成员),这可能会有点棘手,因为您不希望在LINQ中操作原始数据。
因此,您有两个选择:
1.您可以创建一个新的Report实例,并复制所有属性以及一个指标。
2.您可以创建一个带有报告和属性的匿名类型。
我可能更喜欢#2,因为返回修改后的Report可能会令人困惑。所以您可以这样做:
var firstMetric = _ctx.Reports
    .Where(rpt => rpt.bios == mySerial)
    .Select(new { Report = rpt, Metric = rpt.PerformanceMetrics.FirstOrDefault() })
    .FirstOrDefault();

此代码将扫描报告,查找其中 bios == mySerial 的报告,并创建一个新的匿名类型。该匿名类型有一个 Report 成员等于原始报告,以及一个 Metric 成员等于 Report 列表中的第一个度量值。

如果存在报告但没有存在度量值,则会得到一个匿名类型,其 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
只是一个关于负评的建议,如果你要负评,最好附上一条评论,解释为什么这样做,这样作者就可以了解问题所在。 - James Michael Hare

2
你是否在寻找类似这样的东西?
var reportMetric = (from r in _ctx.Reports select r.PerformanceMetric where r.Bios == mySerial).FirstOrDefault();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接