EF - 从完整的子项列表中查找父列表的性能问题

时间:2016-06-24 08:48:12

标签: c# performance entity-framework linq linq-to-entities

我正在使用Entity Framework并遇到了一个性能问题,可归结为以下问题。我有两个实体,ConditionConditionItem,定义如下:

public class Condition
{  
   [Key]
   public int Id { get; set; }
   public virtual HashSet<ConditionItem> ConditionItems { get; set; }
}

public class ConditionItem : BaseEntity
{
   [Key]
   public int Id { get; set; }
   public int ConditionId { get; set; } 
   public int OptionId { get; set; }
   // ... Other properties not shown for clarity
   [ForeignKey("ConditionId")]
   public virtual Condition Condition { get; set; }
   [ForeignKey("OptionId")]
   public virtual Option Option { get; set; }
}

实体Option的定义与问题无关。

鉴于OptionId为Hashset<int>,之后我们将其称为hset,我需要能够:

  • 返回条件的Id的值,如果存在此类条件,则其条件ItemItems的OptionId 完全的相关列表与hset的值匹配。
  • 否则,请创建新的Condition及其关联的ConditionItem,根据OptionId中的值设置其hset属性,然后返回Id新创建的Condition

为此,我首先需要检查条件是否存在。为此,我使用以下Linq查询:

Conditions.FirstOrDefault(x => hset.Count == x.ConditionItems.Count && x.ConditionItems.All(y => hset.Contains(y.OptionId))

如果上述查询返回Condition,我可以轻松访问并返回其Id。如果它返回null,我知道我必须创建一个新的Condition

虽然上述工作正如预期的那样,但在运行大型数据集时,它的速度非常慢。例如,我们目前有大约50,000个条件和大约50万个ConditionItems,并且需要超过500秒才能返回15,000 现有条件的Id。为了澄清,这只是读取数据库,没有涉及创建/ SaveChanges

我希望我们的数据集将继续增长约10倍。

有没有人对如何显着提高性能有任何见解?

编辑:

如评论部分所示,此过程涉及太多数据库请求,导致上述缓慢。

我已经考虑先下载整个数据集,然后再执行Linq查询。这在尝试识别大量条件时会有所帮助(大约时间减半,但仍然不够好),但这会对更少的条件产生非常显着的负面影响。

我希望恢复存储过程,但在此之前确保不存在其他方法。

本质上,我希望,如果IEnumerable<Hashset<int>>表示上面提到的“hset”集合,可以有一种快速的方法来检索ConditionId值的列表, sametime创建了需要创建的Condition个实体。

0 个答案:

没有答案