在实体中查找对象和加载实体,Foreach或使用LinQ ON c#的地方获得最佳性能

本文关键字:实体 ON LinQ 方获得 性能 最佳 对象 查找 加载 Foreach | 更新日期: 2023-09-27 18:06:45

我需要关联几个实体。现在,代码加载第一个实体,然后使用foreach循环进行迭代,如果当前行与另一个实体的记录的属性匹配,则在每个记录上进行搜索。比如:

  foreach (Entity1 e1 in entity1List)
  {
   foreach (Entity2 e2 in entity2List)
   {
    if (e2.Id == e1.Id)
    {
     //Do something
    }
   }
  }

但是实体有很多记录,表现不佳。我想提高使用linQ搜索记录的速度。

var list = entity2List。其中(e2 => entity1.)任意(e1 => e1)。Id == e2.Id));

  foreach (Entity2 e2 in list )
  {
  //Do something
  }

但我不知道这是否真的有助于表现。此外,我想知道在这种情况下加载实体的最佳模型。请提供一些建议或阅读链接或比较执行时间的工具。

我使用了很多连接的每个实体的加载器,但是分开的,因为,测试与其他情况下的行是很多,时间从执行数据库上的查询是太多了,所以现在的实体是独立的,我想通过代码创建依赖关系。

在实体中查找对象和加载实体,Foreach或使用LinQ ON c#的地方获得最佳性能

如果两个实体集都是列表,使用LINQ Where不会给你带来性能提升,因为它相当于你当前的线性搜索算法,时间复杂度为0 (M * N)。

然而,你可以通过使用LINQ GroupJoin方法获得更好的O(M + N)时间复杂度算法(因此性能),该方法内部使用相当有效的基于哈希的查找来关联两个序列:

var list = from e1 in entity1List
           join e2 in entity2List on e1.Id equals e2.Id into e2Group
           select new { e1, e2Group };
foreach (var item in list)
{
    var e1 = item.e1;
    foreach (var e2 in item.e2Group)
    {
        //Do something
    }
}

如果你不需要嵌套的foreach循环处理,你可以使用Join代替,这甚至更有效:

var list = from e1 in entity1List
           join e2 in entity2List on e1.Id equals e2.Id
           select new { e1, e2 };
foreach (var item in list)
{
    var e1 = item.e1;
    var e2 = item.e2;
    //Do something
}

正如@DavidL所说,您可能希望测试两个解决方案,看看会发生什么。另一种选择是对第一个集合进行散列,然后按键在那里搜索。它应该会影响性能。

的例子:

var e1ById = entity1List.GroupBy(x => x.Id).ToDictionary(x => x.Key); //you can skip the GroupBy if you know Id is a unique key)
foreach(var e2 in entity2List.Where(x => e1ById.ContainsKey(e2.Id)))
{
    //Do something
}

或者使用列表来存储键:

var keys = entity1List.Select(x => x.Id).Distinct().ToList();
foreach(var e2 in entity2List.Where(x => keys.Contains(x.Id))
{
    //Do something
}

在任何情况下,性能取决于初始集合长度,因此尝试不同的解决方案并注意时间。

一般来说,如果性能是您主要关心的问题,您通常最好编写自己的优化算法。由于开销,LINQ肯定会比最优算法慢。然而,LINQ是优雅的,对于代码的可维护性非常有用。所以,选择权在你!

在这种特殊情况下,您可以使用Intersect()方法,这比您当前的实现更有效,更简单。

foreach (var element in entity1List.Intersect(entity2List))
{
// Do something
}