干得好。我已经将您的代码直接翻译成 LINQ,希望能帮助您了解我是如何转换它的。
请注意let
关键字的使用,它允许您声明一个范围变量(它允许您执行一次修剪,然后在多个地方使用结果)。
还要注意group by
LINQ 查询底部的使用,以确保我们只获取每个 documentID 的第一次出现。
IList iListReport = obj.GetClosedReports();
var query = from item in reportStatistic
let sRepType = item.ReportName.Trim()
from taskInfo in iListReport
let reportName = taskInfo.DocumentName.Trim()
where string.Compare(sRepType, reportName, true) == 0
&& taskInfo.ActionID == Convert.ToInt16(ReportAction.Close)
//here's how we make sure we don't get the same documentID twice
//we group by the id and then take the first
group taskInfo by taskInfo.DocumentID into grouping
select grouping.First().DocumentID;
var lastClosedReport = query.ToList();
iClosedreportCount = lastClosedReport.Count;
如何将 foreach 循环转换为 LINQ
以下是您的代码与 LINQ 版本的一些比较,以帮助您在某个时候必须再次进行转换。希望这将帮助其他必须将 foreach 循环转换为 LINQ 的人。
1. foreach 和 from
您可以将 foreach 子句直接交换为 LINQ from 子句。你可以看到:
foreach (ReportStatisticsInfo item in reportStatistic)
变成了这样:
from item in reportStatistic
2) 变量声明和 let 关键字
在 foreach 中声明变量时,可以将它们换成 LINQ let 语句。你可以看到这个声明:
sRepType = item.ReportName.Trim();
已经成为:
let sRepType = item.ReportName.Trim()
3) if 语句和 where 子句
您的 if 语句可以进入 where 子句。可以看到以下两个 if 语句:
if (string.Compare(sRepType, reportName, true) == 0)
if (taskInfo.ActionID == Convert.ToInt16(ReportAction.Close)
变成了这个where子句
where string.Compare(sRepType, reportName, true) == 0
&& taskInfo.ActionID == Convert.ToInt16(ReportAction.Close)
4) 使用 group by 删除重复项。
到目前为止,一切都非常简单,因为一切都只是直接交换。最棘手的部分是防止重复出现在结果列表中的代码。
if (taskInfo.ActionID == Convert.ToInt16(ReportAction.Close)
&& !lastClosedReport.Contains(taskInfo.DocumentID))
{
iClosedreportCount += 1;
lastClosedReport.Add(taskInfo.DocumentID);
}
这很棘手,因为它是我们在 LINQ 中唯一需要做一些不同的部分。
首先,我们按“DocumentID”对“taskInfo”进行分组。
group taskInfo by taskInfo.DocumentID into grouping
然后我们从每个分组中取出第一个 taskInfo 并获取它的 ID。
select grouping.First().DocumentID;
关于 Distinct 的说明
很多人尝试使用 Distinct 来消除重复项。当我们使用原始类型时这很好,但是当您使用对象集合时这可能会失败。当您使用对象时,Distinct 将对两个对象进行参考比较。这将无法匹配不同实例但恰好具有相同 ID 的对象。
如果您需要根据对象中的特定属性删除重复项,那么最好的方法是使用 group by。