如何在Entity Framework中过滤重复项,从而将性能损失降到最低?

时间:2019-06-09 10:49:33

标签: c# entity-framework

如何改善以下代码的性能?

我正在从列表中的外部Web服务加载carItems。 检查carItem是否在EF中存在。 如果carItem是新的,则将其映射到carsCol并添加到数据库中。有哪些简单的方法可以使用代码来提高其性能?

        carItems = carItems.Where(x => x.Name == "Tesla");

        // Filter existing cars
        List<Car> carsCol = new List<Car>();
        foreach (var item in carItems)
        {
            if (GetById(item.Id) == null)
            {
                carsCol.Add(item);
            }
        }

        Entities.AddRange(carsCol);

3 个答案:

答案 0 :(得分:1)

根据情况,您可以通过在foreach之前进行一次查询来尝试找出数据库中已经存在的ID。

var newCarItemIds = carItems.Select(x => x.Id);
var alreadyExistentCarItemIds = Entities.CarItems.Where(x => newCarItemIds.Contains(x.Id)).Select(x=>x.Id);

foreach(var item in carItems)
{
    if(!alreadyExistentCarItemIds.Contains(x))
    {
        carsCol.Add(item);
    }
}

答案 1 :(得分:0)

您可以使用Distinct Linq函数:example 您必须实现IEquatable接口

答案 2 :(得分:0)

我会建议这个。您可以对从API和现有API中获得的汽车进行left outter join处理。比得到的新车还要多。

var newCars = (from c in carItems 
          join e in Entities.CarItems on c.Id equals e.Id into g
          from x in g.DefaultIfEmpty()
          select new { c, IsNew = x == null }).Where(x = x.IsNew).ToList()

因此,您只对数据库进行一次访问。同样,在使用IEnumerable时将其转换为列表或数组总是很好的做法,这样,每次迭代该对象时,都不会在数据库中运行查询。