使用LINQ查询大量数据时IEnumerable类型的性能问题

时间:2018-11-21 08:36:56

标签: linq ienumerable query-performance

我正在使用LINQ对具有大量数据(超过一百万)的List类型变量执行查询。出于性能目的,我使用IEnumerable存储结果,但是当我尝试访问它时会稍有延迟。

具体来说,我想查看查询是否产生任何结果,但是当我使用.Count()或.Any()函数时,性能会下降。

我了解到,对于IEnumerable类型,查询的执行发生在需要时,因此会延迟。有没有办法查看IEnumerable内部是否包含元素而没有那么多延迟?

这就是我要运行的。

IEnumerable<Entity> matchingEntities = entities.Where(e => e.Names.Any(n => myEntity.Names.Any(entityName => entityName.CompareNameObjects(n))));

这是我的课程

public class Entity
{
   public string EntityIdentifier { get; set; }
   public List<Name> Names { get; set; }
}

public class Name
{
    public string FullName { get; set; }
    public string NameType { get; set; }

    public bool CompareNameObjects(Name name2)
    {
        return FullName == name2.FullName &&
               NameType == name2.NameType;
    }
}

实体是我所有对象的列表,我想检查 myEntity 是否具有与集合中另一个实体相同的名称。

已编辑:

数据结构类似于2类(实体和名称)。通过从XML格式的数据库中选择所有实体及其名称来创建实体,然后将XML转换为List,如下所示:

List<Entity> entities = new List<Entity>();
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["myCS"].ConnectionString))
{
    conn.Open();
    SqlCommand cmd = new SqlCommand("GetAllEntities", conn);
    cmd.CommandType = CommandType.StoredProcedure;

    string entitiesXml = "";
    using (SqlDataReader rdr = cmd.ExecuteReader())
    {
        while (rdr.Read())
        {
            entitiesXml += rdr["XmlString"].ToString();
        }
    }

    using (TextReader reader = new StringReader(entitiesXml))
        entities = (Entity)xmlSerializer.Deserialize(reader);

    conn.Close();
}

GetAllEntities (Stored Procedure):
declare @xmlString nvarchar(max) =(
    select  e.EntityIdentifier,
        (
            select  n.[Full Name]  as 'FullName', 
                    n.[Name Type]  as 'NameType'
            from tblNames n
            where e.EntityID=n.[Entity_ID]
            for xml path('Name'), type
        )
    from tblEntities e 
    order by e.EntityID
    for xml path('Entity')
) 
select @xmlString as XmlString

1 个答案:

答案 0 :(得分:0)

基本上,应该避免从数据库中获取所有数据,然后使用C#代码对其进行过滤。这会花费很多精力。

但是,为了快速解决问题,您可以通过首先在“字典”表单中准备条件来提高性能。

 // Let's say you have myEntity here
 var myEntity = new Entity();
 var entities = new List<Entity>();

 // You should prepare the list of name that you wanna to find before you do it so that you don't have to make it repeatedly for every iteration
 var names = myEntity.Names.Select(p=> p.FullName + p.NameType ).ToDictionary(p=>p, p=>p);

 IEnumerable<Entity> matchingEntities = entities.Where(e => e.Names.Any(n => names.ContainsKey(n.FullName + n.NameType)));

这只是一个示例,可以给您带来更多的想法。您可以提高更多。希望它能对您有所帮助