Entity framework performance when using methods in the select clause












0














I'm looking at the SQL generated when performing simple select queries. I'm using code first with the sample blog context from nuget.



If the following is run:



BlogContext _context = new BlogContext();
var comments = _context.Comments.Select(c => new CommentReadOnly {Author = c.Author});
var count = comments.Count();


The following SQL is produced:



SELECT 
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT(1) AS [A1]
FROM [dbo].[Comments] AS [Extent1]
) AS [GroupBy1]


Where the count is performed in the SQL which is expected.



However if I change the code to look like this:



BlogContext _context = new BlogContext();
var comments = _context.Comments.Select(c => new CommentReadOnly {Author = c.Author});
var count = comments.Count();

private CommentReadOnly ToCommentReadOnly(Comment comment)
{
return new CommentReadOnly
{
Author = comment.Author,
};
}


The following SQL is produced:



SELECT 
[Extent1].[ID] AS [ID],
[Extent1].[PostID] AS [PostID],
[Extent1].[Text] AS [Text],
[Extent1].[Author] AS [Author]
FROM [dbo].[Comments] AS [Extent1]


With the count done in code.



The reason (I think) is because the first is returned as IQueryable where as the second is IEnumerable.



Is it possible to return the second query as IQueryable without executing the SQL?



The reason I ask is that I'm creating a generic repository layer that can query my entities and convert them to the required type (in the example above comment might have a couple of different 'readonly' objects). I don't want the SQL executing so early as paging may be done or other filtering in different situations.










share|improve this question
























  • Aren't the two code snippets exactly the same? The query is excuted with .Count() and I see no difference in the code before .Count().
    – Slauma
    Oct 19 '11 at 16:09
















0














I'm looking at the SQL generated when performing simple select queries. I'm using code first with the sample blog context from nuget.



If the following is run:



BlogContext _context = new BlogContext();
var comments = _context.Comments.Select(c => new CommentReadOnly {Author = c.Author});
var count = comments.Count();


The following SQL is produced:



SELECT 
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT(1) AS [A1]
FROM [dbo].[Comments] AS [Extent1]
) AS [GroupBy1]


Where the count is performed in the SQL which is expected.



However if I change the code to look like this:



BlogContext _context = new BlogContext();
var comments = _context.Comments.Select(c => new CommentReadOnly {Author = c.Author});
var count = comments.Count();

private CommentReadOnly ToCommentReadOnly(Comment comment)
{
return new CommentReadOnly
{
Author = comment.Author,
};
}


The following SQL is produced:



SELECT 
[Extent1].[ID] AS [ID],
[Extent1].[PostID] AS [PostID],
[Extent1].[Text] AS [Text],
[Extent1].[Author] AS [Author]
FROM [dbo].[Comments] AS [Extent1]


With the count done in code.



The reason (I think) is because the first is returned as IQueryable where as the second is IEnumerable.



Is it possible to return the second query as IQueryable without executing the SQL?



The reason I ask is that I'm creating a generic repository layer that can query my entities and convert them to the required type (in the example above comment might have a couple of different 'readonly' objects). I don't want the SQL executing so early as paging may be done or other filtering in different situations.










share|improve this question
























  • Aren't the two code snippets exactly the same? The query is excuted with .Count() and I see no difference in the code before .Count().
    – Slauma
    Oct 19 '11 at 16:09














0












0








0







I'm looking at the SQL generated when performing simple select queries. I'm using code first with the sample blog context from nuget.



If the following is run:



BlogContext _context = new BlogContext();
var comments = _context.Comments.Select(c => new CommentReadOnly {Author = c.Author});
var count = comments.Count();


The following SQL is produced:



SELECT 
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT(1) AS [A1]
FROM [dbo].[Comments] AS [Extent1]
) AS [GroupBy1]


Where the count is performed in the SQL which is expected.



However if I change the code to look like this:



BlogContext _context = new BlogContext();
var comments = _context.Comments.Select(c => new CommentReadOnly {Author = c.Author});
var count = comments.Count();

private CommentReadOnly ToCommentReadOnly(Comment comment)
{
return new CommentReadOnly
{
Author = comment.Author,
};
}


The following SQL is produced:



SELECT 
[Extent1].[ID] AS [ID],
[Extent1].[PostID] AS [PostID],
[Extent1].[Text] AS [Text],
[Extent1].[Author] AS [Author]
FROM [dbo].[Comments] AS [Extent1]


With the count done in code.



The reason (I think) is because the first is returned as IQueryable where as the second is IEnumerable.



Is it possible to return the second query as IQueryable without executing the SQL?



The reason I ask is that I'm creating a generic repository layer that can query my entities and convert them to the required type (in the example above comment might have a couple of different 'readonly' objects). I don't want the SQL executing so early as paging may be done or other filtering in different situations.










share|improve this question















I'm looking at the SQL generated when performing simple select queries. I'm using code first with the sample blog context from nuget.



If the following is run:



BlogContext _context = new BlogContext();
var comments = _context.Comments.Select(c => new CommentReadOnly {Author = c.Author});
var count = comments.Count();


The following SQL is produced:



SELECT 
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT(1) AS [A1]
FROM [dbo].[Comments] AS [Extent1]
) AS [GroupBy1]


Where the count is performed in the SQL which is expected.



However if I change the code to look like this:



BlogContext _context = new BlogContext();
var comments = _context.Comments.Select(c => new CommentReadOnly {Author = c.Author});
var count = comments.Count();

private CommentReadOnly ToCommentReadOnly(Comment comment)
{
return new CommentReadOnly
{
Author = comment.Author,
};
}


The following SQL is produced:



SELECT 
[Extent1].[ID] AS [ID],
[Extent1].[PostID] AS [PostID],
[Extent1].[Text] AS [Text],
[Extent1].[Author] AS [Author]
FROM [dbo].[Comments] AS [Extent1]


With the count done in code.



The reason (I think) is because the first is returned as IQueryable where as the second is IEnumerable.



Is it possible to return the second query as IQueryable without executing the SQL?



The reason I ask is that I'm creating a generic repository layer that can query my entities and convert them to the required type (in the example above comment might have a couple of different 'readonly' objects). I don't want the SQL executing so early as paging may be done or other filtering in different situations.







entity-framework entity-framework-4.1 code-first






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 19 '18 at 16:38









Cœur

17.4k9103145




17.4k9103145










asked Oct 19 '11 at 15:44









lancscoder

5,29973865




5,29973865












  • Aren't the two code snippets exactly the same? The query is excuted with .Count() and I see no difference in the code before .Count().
    – Slauma
    Oct 19 '11 at 16:09


















  • Aren't the two code snippets exactly the same? The query is excuted with .Count() and I see no difference in the code before .Count().
    – Slauma
    Oct 19 '11 at 16:09
















Aren't the two code snippets exactly the same? The query is excuted with .Count() and I see no difference in the code before .Count().
– Slauma
Oct 19 '11 at 16:09




Aren't the two code snippets exactly the same? The query is excuted with .Count() and I see no difference in the code before .Count().
– Slauma
Oct 19 '11 at 16:09












2 Answers
2






active

oldest

votes


















0














I don't see any difference in those two queries. However, I guess you want to return a IQueryable object to the client so the client can perform further filtering and get the count from there.



You can simply return the object without doing the select and let the client do the rest.



return _context.Comments


The client can perform additional filtering on this IQueryable object






share|improve this answer





























    0














    I think in your second query you execute the function ToCommentReadOnly() so this can't be done entirely in SQL and you end up with a Linq To Objects (IEnumerable).



    But you state that you want to return an IQueryable from your Repository. This is not a recommended practice! The code to access the data should be hidden inside your repository otherwhise you will run into problems.



    Say for example that your repository (which encapsulates your ObjectContext) goes out of scope after which you try to enumerate the IQueryable result the repository gave you. This will throw an error because the IQueryable can't be executed anymore.



    If you expose an IQueryable from your Repository you give the end user of your Repository all the freedom they want in building their own queries, which is the thing you want to avoid by adding a repository!



    So returning an IEnumerable from your Repository is a good thing :)






    share|improve this answer





















    • I would not agree that exposing IQueryable and a context reference outside of the respository is generally "not a recommended practice". There are as many reason in favor to do so (simplicity, direct projection into ViewModels, handling large data and data virtualization in desktop apps, lazy loading, etc.) as against this practice.
      – Slauma
      Oct 19 '11 at 19:33










    • Well one example is when you are trying to optimize your queries. In our repositories we use CompiledQueries for performance. If we would expose IQueryable instead of IEnumerable, the compiling would be useless if the users of the repository would alter the queries and use the precompiling. And by using IQueryable you also couples your your code to the Entity Framework. The whole idea of the Repository pattern is to be independent of your persistent mechanism. We expose POCO's or custom DTO's from our data layer which suit the needs of the upper layers.
      – Wouter de Kort
      Oct 19 '11 at 19:55










    • I know :) These are the good points and the theory always sounds good. But rarely the costs in practice (in time and development effort) are mentioned when it comes to "Independency of persistence mechanism" and encapsulation of data access. Don't misunderstand me, I don't say that your points are never correct, but I disagree that the points are always correct.
      – Slauma
      Oct 19 '11 at 20:22











    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%2f7824056%2fentity-framework-performance-when-using-methods-in-the-select-clause%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    I don't see any difference in those two queries. However, I guess you want to return a IQueryable object to the client so the client can perform further filtering and get the count from there.



    You can simply return the object without doing the select and let the client do the rest.



    return _context.Comments


    The client can perform additional filtering on this IQueryable object






    share|improve this answer


























      0














      I don't see any difference in those two queries. However, I guess you want to return a IQueryable object to the client so the client can perform further filtering and get the count from there.



      You can simply return the object without doing the select and let the client do the rest.



      return _context.Comments


      The client can perform additional filtering on this IQueryable object






      share|improve this answer
























        0












        0








        0






        I don't see any difference in those two queries. However, I guess you want to return a IQueryable object to the client so the client can perform further filtering and get the count from there.



        You can simply return the object without doing the select and let the client do the rest.



        return _context.Comments


        The client can perform additional filtering on this IQueryable object






        share|improve this answer












        I don't see any difference in those two queries. However, I guess you want to return a IQueryable object to the client so the client can perform further filtering and get the count from there.



        You can simply return the object without doing the select and let the client do the rest.



        return _context.Comments


        The client can perform additional filtering on this IQueryable object







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Oct 19 '11 at 18:02









        MNIK

        80131020




        80131020

























            0














            I think in your second query you execute the function ToCommentReadOnly() so this can't be done entirely in SQL and you end up with a Linq To Objects (IEnumerable).



            But you state that you want to return an IQueryable from your Repository. This is not a recommended practice! The code to access the data should be hidden inside your repository otherwhise you will run into problems.



            Say for example that your repository (which encapsulates your ObjectContext) goes out of scope after which you try to enumerate the IQueryable result the repository gave you. This will throw an error because the IQueryable can't be executed anymore.



            If you expose an IQueryable from your Repository you give the end user of your Repository all the freedom they want in building their own queries, which is the thing you want to avoid by adding a repository!



            So returning an IEnumerable from your Repository is a good thing :)






            share|improve this answer





















            • I would not agree that exposing IQueryable and a context reference outside of the respository is generally "not a recommended practice". There are as many reason in favor to do so (simplicity, direct projection into ViewModels, handling large data and data virtualization in desktop apps, lazy loading, etc.) as against this practice.
              – Slauma
              Oct 19 '11 at 19:33










            • Well one example is when you are trying to optimize your queries. In our repositories we use CompiledQueries for performance. If we would expose IQueryable instead of IEnumerable, the compiling would be useless if the users of the repository would alter the queries and use the precompiling. And by using IQueryable you also couples your your code to the Entity Framework. The whole idea of the Repository pattern is to be independent of your persistent mechanism. We expose POCO's or custom DTO's from our data layer which suit the needs of the upper layers.
              – Wouter de Kort
              Oct 19 '11 at 19:55










            • I know :) These are the good points and the theory always sounds good. But rarely the costs in practice (in time and development effort) are mentioned when it comes to "Independency of persistence mechanism" and encapsulation of data access. Don't misunderstand me, I don't say that your points are never correct, but I disagree that the points are always correct.
              – Slauma
              Oct 19 '11 at 20:22
















            0














            I think in your second query you execute the function ToCommentReadOnly() so this can't be done entirely in SQL and you end up with a Linq To Objects (IEnumerable).



            But you state that you want to return an IQueryable from your Repository. This is not a recommended practice! The code to access the data should be hidden inside your repository otherwhise you will run into problems.



            Say for example that your repository (which encapsulates your ObjectContext) goes out of scope after which you try to enumerate the IQueryable result the repository gave you. This will throw an error because the IQueryable can't be executed anymore.



            If you expose an IQueryable from your Repository you give the end user of your Repository all the freedom they want in building their own queries, which is the thing you want to avoid by adding a repository!



            So returning an IEnumerable from your Repository is a good thing :)






            share|improve this answer





















            • I would not agree that exposing IQueryable and a context reference outside of the respository is generally "not a recommended practice". There are as many reason in favor to do so (simplicity, direct projection into ViewModels, handling large data and data virtualization in desktop apps, lazy loading, etc.) as against this practice.
              – Slauma
              Oct 19 '11 at 19:33










            • Well one example is when you are trying to optimize your queries. In our repositories we use CompiledQueries for performance. If we would expose IQueryable instead of IEnumerable, the compiling would be useless if the users of the repository would alter the queries and use the precompiling. And by using IQueryable you also couples your your code to the Entity Framework. The whole idea of the Repository pattern is to be independent of your persistent mechanism. We expose POCO's or custom DTO's from our data layer which suit the needs of the upper layers.
              – Wouter de Kort
              Oct 19 '11 at 19:55










            • I know :) These are the good points and the theory always sounds good. But rarely the costs in practice (in time and development effort) are mentioned when it comes to "Independency of persistence mechanism" and encapsulation of data access. Don't misunderstand me, I don't say that your points are never correct, but I disagree that the points are always correct.
              – Slauma
              Oct 19 '11 at 20:22














            0












            0








            0






            I think in your second query you execute the function ToCommentReadOnly() so this can't be done entirely in SQL and you end up with a Linq To Objects (IEnumerable).



            But you state that you want to return an IQueryable from your Repository. This is not a recommended practice! The code to access the data should be hidden inside your repository otherwhise you will run into problems.



            Say for example that your repository (which encapsulates your ObjectContext) goes out of scope after which you try to enumerate the IQueryable result the repository gave you. This will throw an error because the IQueryable can't be executed anymore.



            If you expose an IQueryable from your Repository you give the end user of your Repository all the freedom they want in building their own queries, which is the thing you want to avoid by adding a repository!



            So returning an IEnumerable from your Repository is a good thing :)






            share|improve this answer












            I think in your second query you execute the function ToCommentReadOnly() so this can't be done entirely in SQL and you end up with a Linq To Objects (IEnumerable).



            But you state that you want to return an IQueryable from your Repository. This is not a recommended practice! The code to access the data should be hidden inside your repository otherwhise you will run into problems.



            Say for example that your repository (which encapsulates your ObjectContext) goes out of scope after which you try to enumerate the IQueryable result the repository gave you. This will throw an error because the IQueryable can't be executed anymore.



            If you expose an IQueryable from your Repository you give the end user of your Repository all the freedom they want in building their own queries, which is the thing you want to avoid by adding a repository!



            So returning an IEnumerable from your Repository is a good thing :)







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Oct 19 '11 at 18:36









            Wouter de Kort

            29.9k85791




            29.9k85791












            • I would not agree that exposing IQueryable and a context reference outside of the respository is generally "not a recommended practice". There are as many reason in favor to do so (simplicity, direct projection into ViewModels, handling large data and data virtualization in desktop apps, lazy loading, etc.) as against this practice.
              – Slauma
              Oct 19 '11 at 19:33










            • Well one example is when you are trying to optimize your queries. In our repositories we use CompiledQueries for performance. If we would expose IQueryable instead of IEnumerable, the compiling would be useless if the users of the repository would alter the queries and use the precompiling. And by using IQueryable you also couples your your code to the Entity Framework. The whole idea of the Repository pattern is to be independent of your persistent mechanism. We expose POCO's or custom DTO's from our data layer which suit the needs of the upper layers.
              – Wouter de Kort
              Oct 19 '11 at 19:55










            • I know :) These are the good points and the theory always sounds good. But rarely the costs in practice (in time and development effort) are mentioned when it comes to "Independency of persistence mechanism" and encapsulation of data access. Don't misunderstand me, I don't say that your points are never correct, but I disagree that the points are always correct.
              – Slauma
              Oct 19 '11 at 20:22


















            • I would not agree that exposing IQueryable and a context reference outside of the respository is generally "not a recommended practice". There are as many reason in favor to do so (simplicity, direct projection into ViewModels, handling large data and data virtualization in desktop apps, lazy loading, etc.) as against this practice.
              – Slauma
              Oct 19 '11 at 19:33










            • Well one example is when you are trying to optimize your queries. In our repositories we use CompiledQueries for performance. If we would expose IQueryable instead of IEnumerable, the compiling would be useless if the users of the repository would alter the queries and use the precompiling. And by using IQueryable you also couples your your code to the Entity Framework. The whole idea of the Repository pattern is to be independent of your persistent mechanism. We expose POCO's or custom DTO's from our data layer which suit the needs of the upper layers.
              – Wouter de Kort
              Oct 19 '11 at 19:55










            • I know :) These are the good points and the theory always sounds good. But rarely the costs in practice (in time and development effort) are mentioned when it comes to "Independency of persistence mechanism" and encapsulation of data access. Don't misunderstand me, I don't say that your points are never correct, but I disagree that the points are always correct.
              – Slauma
              Oct 19 '11 at 20:22
















            I would not agree that exposing IQueryable and a context reference outside of the respository is generally "not a recommended practice". There are as many reason in favor to do so (simplicity, direct projection into ViewModels, handling large data and data virtualization in desktop apps, lazy loading, etc.) as against this practice.
            – Slauma
            Oct 19 '11 at 19:33




            I would not agree that exposing IQueryable and a context reference outside of the respository is generally "not a recommended practice". There are as many reason in favor to do so (simplicity, direct projection into ViewModels, handling large data and data virtualization in desktop apps, lazy loading, etc.) as against this practice.
            – Slauma
            Oct 19 '11 at 19:33












            Well one example is when you are trying to optimize your queries. In our repositories we use CompiledQueries for performance. If we would expose IQueryable instead of IEnumerable, the compiling would be useless if the users of the repository would alter the queries and use the precompiling. And by using IQueryable you also couples your your code to the Entity Framework. The whole idea of the Repository pattern is to be independent of your persistent mechanism. We expose POCO's or custom DTO's from our data layer which suit the needs of the upper layers.
            – Wouter de Kort
            Oct 19 '11 at 19:55




            Well one example is when you are trying to optimize your queries. In our repositories we use CompiledQueries for performance. If we would expose IQueryable instead of IEnumerable, the compiling would be useless if the users of the repository would alter the queries and use the precompiling. And by using IQueryable you also couples your your code to the Entity Framework. The whole idea of the Repository pattern is to be independent of your persistent mechanism. We expose POCO's or custom DTO's from our data layer which suit the needs of the upper layers.
            – Wouter de Kort
            Oct 19 '11 at 19:55












            I know :) These are the good points and the theory always sounds good. But rarely the costs in practice (in time and development effort) are mentioned when it comes to "Independency of persistence mechanism" and encapsulation of data access. Don't misunderstand me, I don't say that your points are never correct, but I disagree that the points are always correct.
            – Slauma
            Oct 19 '11 at 20:22




            I know :) These are the good points and the theory always sounds good. But rarely the costs in practice (in time and development effort) are mentioned when it comes to "Independency of persistence mechanism" and encapsulation of data access. Don't misunderstand me, I don't say that your points are never correct, but I disagree that the points are always correct.
            – Slauma
            Oct 19 '11 at 20:22


















            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.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • 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%2f7824056%2fentity-framework-performance-when-using-methods-in-the-select-clause%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

            MongoDB - Not Authorized To Execute Command

            How to fix TextFormField cause rebuild widget in Flutter

            in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith