Performance issue in IEnumerable type when querying large amount of data with LINQ












0















I'm using LINQ to execute a query on a List type variable with a large amount of data (over a million). For performance purposes I'm using IEnumerable to store the results but when I try to access it there is a slight delay.



Specifically I want to see if the query produced any results, but when I use the .Count() or .Any() functions the performance drops.



I read that for IEnumerable types the execution of the query happens at the time of need, hence the delay. Is there a way to see if the IEnumerable has elements inside it without having that much delay?



This is what I'm trying to run.



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


and here are my classes



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;
}
}


entities is a list of all my objects and I want to check if myEntity has any Names identical with another entity in the set.



EDITED:



The data structure is similar to the 2 classes (Entity and Name). The entities are created by selecting all the entities, along with their names, from the database in XML format and then I convert the XML to a List as such:



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









share|improve this question




















  • 1





    Show us where "entities" is from. If you are using EF, to get the best performance, you should avoid using Enumerable as much as possible

    – Hieu Le
    Nov 21 '18 at 8:41











  • Entities comes from a query on SQL Server. To get all the entities I have a small delay but I don't mind that.

    – Vasos Hadjioannou
    Nov 21 '18 at 8:45













  • You cannot use CompareNameObjects in EF because it forces your code to run on RAM, not in SQL Server which is very slow. Please rephrase your condition to filter data directly. "Any" can be translated to SQL scripts, so no problem for it. Ex: entities.Where(e => e.Names.Any(n => myEntity.Names.Any(entityName => entityName.FullName == n.FullName && entityName.NameType == n.NameType)));

    – Hieu Le
    Nov 21 '18 at 9:00













  • Tried this but i get the same result

    – Vasos Hadjioannou
    Nov 21 '18 at 9:14











  • I cannot tell you more if I don't know the table structures and what entities is

    – Hieu Le
    Nov 21 '18 at 9:44


















0















I'm using LINQ to execute a query on a List type variable with a large amount of data (over a million). For performance purposes I'm using IEnumerable to store the results but when I try to access it there is a slight delay.



Specifically I want to see if the query produced any results, but when I use the .Count() or .Any() functions the performance drops.



I read that for IEnumerable types the execution of the query happens at the time of need, hence the delay. Is there a way to see if the IEnumerable has elements inside it without having that much delay?



This is what I'm trying to run.



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


and here are my classes



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;
}
}


entities is a list of all my objects and I want to check if myEntity has any Names identical with another entity in the set.



EDITED:



The data structure is similar to the 2 classes (Entity and Name). The entities are created by selecting all the entities, along with their names, from the database in XML format and then I convert the XML to a List as such:



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









share|improve this question




















  • 1





    Show us where "entities" is from. If you are using EF, to get the best performance, you should avoid using Enumerable as much as possible

    – Hieu Le
    Nov 21 '18 at 8:41











  • Entities comes from a query on SQL Server. To get all the entities I have a small delay but I don't mind that.

    – Vasos Hadjioannou
    Nov 21 '18 at 8:45













  • You cannot use CompareNameObjects in EF because it forces your code to run on RAM, not in SQL Server which is very slow. Please rephrase your condition to filter data directly. "Any" can be translated to SQL scripts, so no problem for it. Ex: entities.Where(e => e.Names.Any(n => myEntity.Names.Any(entityName => entityName.FullName == n.FullName && entityName.NameType == n.NameType)));

    – Hieu Le
    Nov 21 '18 at 9:00













  • Tried this but i get the same result

    – Vasos Hadjioannou
    Nov 21 '18 at 9:14











  • I cannot tell you more if I don't know the table structures and what entities is

    – Hieu Le
    Nov 21 '18 at 9:44
















0












0








0








I'm using LINQ to execute a query on a List type variable with a large amount of data (over a million). For performance purposes I'm using IEnumerable to store the results but when I try to access it there is a slight delay.



Specifically I want to see if the query produced any results, but when I use the .Count() or .Any() functions the performance drops.



I read that for IEnumerable types the execution of the query happens at the time of need, hence the delay. Is there a way to see if the IEnumerable has elements inside it without having that much delay?



This is what I'm trying to run.



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


and here are my classes



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;
}
}


entities is a list of all my objects and I want to check if myEntity has any Names identical with another entity in the set.



EDITED:



The data structure is similar to the 2 classes (Entity and Name). The entities are created by selecting all the entities, along with their names, from the database in XML format and then I convert the XML to a List as such:



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









share|improve this question
















I'm using LINQ to execute a query on a List type variable with a large amount of data (over a million). For performance purposes I'm using IEnumerable to store the results but when I try to access it there is a slight delay.



Specifically I want to see if the query produced any results, but when I use the .Count() or .Any() functions the performance drops.



I read that for IEnumerable types the execution of the query happens at the time of need, hence the delay. Is there a way to see if the IEnumerable has elements inside it without having that much delay?



This is what I'm trying to run.



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


and here are my classes



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;
}
}


entities is a list of all my objects and I want to check if myEntity has any Names identical with another entity in the set.



EDITED:



The data structure is similar to the 2 classes (Entity and Name). The entities are created by selecting all the entities, along with their names, from the database in XML format and then I convert the XML to a List as such:



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






linq ienumerable query-performance






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 21 '18 at 10:17







Vasos Hadjioannou

















asked Nov 21 '18 at 8:36









Vasos HadjioannouVasos Hadjioannou

11




11








  • 1





    Show us where "entities" is from. If you are using EF, to get the best performance, you should avoid using Enumerable as much as possible

    – Hieu Le
    Nov 21 '18 at 8:41











  • Entities comes from a query on SQL Server. To get all the entities I have a small delay but I don't mind that.

    – Vasos Hadjioannou
    Nov 21 '18 at 8:45













  • You cannot use CompareNameObjects in EF because it forces your code to run on RAM, not in SQL Server which is very slow. Please rephrase your condition to filter data directly. "Any" can be translated to SQL scripts, so no problem for it. Ex: entities.Where(e => e.Names.Any(n => myEntity.Names.Any(entityName => entityName.FullName == n.FullName && entityName.NameType == n.NameType)));

    – Hieu Le
    Nov 21 '18 at 9:00













  • Tried this but i get the same result

    – Vasos Hadjioannou
    Nov 21 '18 at 9:14











  • I cannot tell you more if I don't know the table structures and what entities is

    – Hieu Le
    Nov 21 '18 at 9:44
















  • 1





    Show us where "entities" is from. If you are using EF, to get the best performance, you should avoid using Enumerable as much as possible

    – Hieu Le
    Nov 21 '18 at 8:41











  • Entities comes from a query on SQL Server. To get all the entities I have a small delay but I don't mind that.

    – Vasos Hadjioannou
    Nov 21 '18 at 8:45













  • You cannot use CompareNameObjects in EF because it forces your code to run on RAM, not in SQL Server which is very slow. Please rephrase your condition to filter data directly. "Any" can be translated to SQL scripts, so no problem for it. Ex: entities.Where(e => e.Names.Any(n => myEntity.Names.Any(entityName => entityName.FullName == n.FullName && entityName.NameType == n.NameType)));

    – Hieu Le
    Nov 21 '18 at 9:00













  • Tried this but i get the same result

    – Vasos Hadjioannou
    Nov 21 '18 at 9:14











  • I cannot tell you more if I don't know the table structures and what entities is

    – Hieu Le
    Nov 21 '18 at 9:44










1




1





Show us where "entities" is from. If you are using EF, to get the best performance, you should avoid using Enumerable as much as possible

– Hieu Le
Nov 21 '18 at 8:41





Show us where "entities" is from. If you are using EF, to get the best performance, you should avoid using Enumerable as much as possible

– Hieu Le
Nov 21 '18 at 8:41













Entities comes from a query on SQL Server. To get all the entities I have a small delay but I don't mind that.

– Vasos Hadjioannou
Nov 21 '18 at 8:45







Entities comes from a query on SQL Server. To get all the entities I have a small delay but I don't mind that.

– Vasos Hadjioannou
Nov 21 '18 at 8:45















You cannot use CompareNameObjects in EF because it forces your code to run on RAM, not in SQL Server which is very slow. Please rephrase your condition to filter data directly. "Any" can be translated to SQL scripts, so no problem for it. Ex: entities.Where(e => e.Names.Any(n => myEntity.Names.Any(entityName => entityName.FullName == n.FullName && entityName.NameType == n.NameType)));

– Hieu Le
Nov 21 '18 at 9:00







You cannot use CompareNameObjects in EF because it forces your code to run on RAM, not in SQL Server which is very slow. Please rephrase your condition to filter data directly. "Any" can be translated to SQL scripts, so no problem for it. Ex: entities.Where(e => e.Names.Any(n => myEntity.Names.Any(entityName => entityName.FullName == n.FullName && entityName.NameType == n.NameType)));

– Hieu Le
Nov 21 '18 at 9:00















Tried this but i get the same result

– Vasos Hadjioannou
Nov 21 '18 at 9:14





Tried this but i get the same result

– Vasos Hadjioannou
Nov 21 '18 at 9:14













I cannot tell you more if I don't know the table structures and what entities is

– Hieu Le
Nov 21 '18 at 9:44







I cannot tell you more if I don't know the table structures and what entities is

– Hieu Le
Nov 21 '18 at 9:44














1 Answer
1






active

oldest

votes


















0














Basically, you should avoid getting all data from your database then filter it with C# code. It consumes a lot of effort.



However, for quick solution, you can improve performance by preparing your conditions in a Dictionary form firstly.



 // 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)));


This is just an example that may give you more idea. You can improve much more. I hope it can help you






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53408060%2fperformance-issue-in-ienumerable-type-when-querying-large-amount-of-data-with-li%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    Basically, you should avoid getting all data from your database then filter it with C# code. It consumes a lot of effort.



    However, for quick solution, you can improve performance by preparing your conditions in a Dictionary form firstly.



     // 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)));


    This is just an example that may give you more idea. You can improve much more. I hope it can help you






    share|improve this answer




























      0














      Basically, you should avoid getting all data from your database then filter it with C# code. It consumes a lot of effort.



      However, for quick solution, you can improve performance by preparing your conditions in a Dictionary form firstly.



       // 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)));


      This is just an example that may give you more idea. You can improve much more. I hope it can help you






      share|improve this answer


























        0












        0








        0







        Basically, you should avoid getting all data from your database then filter it with C# code. It consumes a lot of effort.



        However, for quick solution, you can improve performance by preparing your conditions in a Dictionary form firstly.



         // 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)));


        This is just an example that may give you more idea. You can improve much more. I hope it can help you






        share|improve this answer













        Basically, you should avoid getting all data from your database then filter it with C# code. It consumes a lot of effort.



        However, for quick solution, you can improve performance by preparing your conditions in a Dictionary form firstly.



         // 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)));


        This is just an example that may give you more idea. You can improve much more. I hope it can help you







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 22 '18 at 4:51









        Hieu LeHieu Le

        541314




        541314
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53408060%2fperformance-issue-in-ienumerable-type-when-querying-large-amount-of-data-with-li%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Guess what letter conforming each word

            Port of Spain

            Run scheduled task as local user group (not BUILTIN)