我正在尝试将下面的每个循环嵌套转换为Linq。但是我仍然无法成功。
var objAct = new List<InformaticsBenchmarkSummary>();
foreach (var item in op)
{
foreach (var lstTp5 in lstTopFive)
{
if (item.UnitOfOperations.ContainsKey(lstTp5.SystemID))
{
var objIbm = new InformaticsBenchmarkSummary();
objIbm.CompanyId = item.CompanyId;
objIbm.CompanyName = item.CompanyName;
objIbm.LocationId = item.LocationId;
objIbm.LocationName = item.LocationName;
objIbm.UnitOfOperations.Add(lstTp5.SystemID,
item.UnitOfOperations[lstTp5.SystemID]);
objAct.Add(objIbm);
}
}
}
其中UnitOfOperations
的类型为Dictionary<int,string>()
;
op
再次List<InformaticsBenchmarkSummary>()
lstTopFive
为List<int>()
我尝试过,类似这样但语法不成功
var output = from item in op
from lstTp5 in lstTopFive
where item.UnitOfOperations.ContainsKey(lstTp5.SystemID)
let v = new InformaticsBenchmarkSummary()
{
CompanyId = item.CompanyId,
CompanyName = item.CompanyName,
LocationId = item.LocationId,
LocationName = item.LocationName
}
.UnitOfOperations.Add(lstTp5.SystemID, item.UnitOfOperations[lstTp5.SystemID])
select v;
嵌套循环完美运行但我认为,linq就可以提高性能。 感谢任何帮助。
答案 0 :(得分:2)
在Linq查询语法中,不可能在select中使用UnitOfOperations.Add
。但是你可以使用Method Chain和SelectMany
方法来实现它:
var objAcu = (op.SelectMany(item => lstTopFive, (item, lstTp5) => new { item, lstTp5 }) // <- Bad readability
.Where(t => t.item.UnitOfOperations.ContainsKey(t.lstTp5.SystemID))
.Select(t =>
{
var objIbm = new InformaticsBenchmarkSummary
{
CompanyId = t.item.CompanyId,
CompanyName = t.item.CompanyName,
LocationId = t.item.LocationId,
LocationName = t.item.LocationName
};
objIbm.UnitOfOperations.Add(t.lstTp5.SystemID, t.item.UnitOfOperations[t.lstTp5.SystemID]);
return objIbm;
})).ToList();
如果属性UnitOfOperations
具有公开set
,则在这种情况下,您可以使用查询语法。
如何替换1 foreach
?按from ... in ...
然后,要替换2 foreach
,请使用2 from ... in ...
var objAct = (from item in op // First foreach loop
from lstTp5 in lstTopFive // Second foreach loop
where item.UnitOfOperations.ContainsKey(lstTp5.SystemID)
select new InformaticsBenchmarkSummary
{
CompanyId = item.CompanyId,
CompanyName = item.CompanyName,
LocationId = item.LocationId,
LocationName = item.LocationName,
UnitOfOperations = { { lstTp5.SystemID, item.UnitOfOperations[lstTp5.SystemID] } }
}).ToList();
但我怀疑它会在这种操作中提高性能。
无论如何,我不明白你想要达到的目的。因为在输出的所有项目中,字典UnitOfOperations
中只有一个且只有一个元素。这真的是你想做的吗?
List<int> systemIdTop5 = lstTopFive.Select(tp5 => tp5.SystemID).ToList();
var objAct = (from item in op
select new InformaticsBenchmarkSummary
{
CompanyId = item.CompanyId,
CompanyName = item.CompanyName,
LocationId = item.LocationId,
LocationName = item.LocationName,
UnitOfOperations = systemIdTop5.Intersect(item.UnitOfOperations.Keys)
.ToDictionary(systemId => systemId, systemId => item.UnitOfOperations[systemId])
}).ToList();
答案 1 :(得分:1)
你很接近,但你不能在LINQ查询中使用void
返回方法。 (如果不是void
- 返回,则v
将是Add()
的结果,这很可能是错误的。)
如果您想为Dictionary
创建新的UnitOfOperations
,则可以将其设置为与其他属性相同的方式。但是如果你不能这样做(可能是因为UnitOfOperations
有一个私有的setter)或者你不想(因为UnitOfOperations
被初始化为你想保留的某个值),你可以使用C#的一个鲜为人知的特性:对象初始化器中的集合初始化器:
UnitOfOperations = { { lstTp5.SystemID, item.UnitOfOperations[lstTp5.SystemID] } }
此代码的效果与您编写的内容相同:
createdObject.UnitOfOperations.Add(lstTp5.SystemID, item.UnitOfOperations[lstTp5.SystemID]);
唯一的区别是它不是一个语句,它是表达式的一部分,这意味着你可以在LINQ查询中使用它。
整个查询将是:
var output = from item in op
from lstTp5 in lstTopFive
where item.UnitOfOperations.ContainsKey(lstTp5.SystemID)
select new InformaticsBenchmarkSummary()
{
CompanyId = item.CompanyId,
CompanyName = item.CompanyName,
LocationId = item.LocationId,
LocationName = item.LocationName,
UnitOfOperations =
{
{ lstTp5.SystemID, item.UnitOfOperations[lstTp5.SystemID] }
}
};
答案 2 :(得分:1)
据我所知,你的UnitOfOperations是你遇到的困难。如果它在构造函数中初始化,您可以使用它:
var output = from item in op
from lstTp5 in lstTopFive
where item.UnitOfOperations.ContainsKey(lstTp5.SystemID)
select
new InformaticsBenchmarkSummary()
{
CompanyId = item.CompanyId,
CompanyName = item.CompanyName,
LocationId = item.LocationId,
LocationName = item.LocationName,
UnitOfOperations = { { lstTp5.SystemID, item.UnitOfOperations[lstTp5.SystemID] } }
};
结果是IEnumerable
,如果您想将其作为列表,请致电output.ToList()
。
两个旁注:
UnitOfOperations
),但我想这是理想的。在最糟糕的情况下,op
中的所有项目都有一个UnitOfOperations
,其中包含SystemID
中的所有lstTopFive
,在op.Count()*lstTopFive.Count()
中为我们提供了总共output
个项目1}}。答案 3 :(得分:0)
这可以帮助你:
var output = from item in op
join lstTp5 in lstTopFive on item.UnitOfOperations.Key equals lstTp5.SystemID
select new InformaticsBenchmarkSummary
{
CompanyId = item.CompanyId,
CompanyName = item.CompanyName,
LocationId = item.LocationId,
LocationName = item.LocationName,
UnitOfOperations = item.UnitOfOperations
};