<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ali Shamekhi</title>
    <description>The latest articles on DEV Community by Ali Shamekhi (@ali_shamekhi_9f01577ed87d).</description>
    <link>https://dev.to/ali_shamekhi_9f01577ed87d</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3420984%2F865620cd-b09a-4be8-9a24-832828dd945a.jpg</url>
      <title>DEV Community: Ali Shamekhi</title>
      <link>https://dev.to/ali_shamekhi_9f01577ed87d</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ali_shamekhi_9f01577ed87d"/>
    <language>en</language>
    <item>
      <title>Why Entity Framework Core Adds an Extra 'ORDER BY' When Including a Collection Navigation Property</title>
      <dc:creator>Ali Shamekhi</dc:creator>
      <pubDate>Fri, 08 Aug 2025 06:50:21 +0000</pubDate>
      <link>https://dev.to/ali_shamekhi_9f01577ed87d/why-entity-framework-core-adds-an-extra-order-by-when-including-a-collection-navigation-property-2bdf</link>
      <guid>https://dev.to/ali_shamekhi_9f01577ed87d/why-entity-framework-core-adds-an-extra-order-by-when-including-a-collection-navigation-property-2bdf</guid>
      <description>&lt;p&gt;When working with Entity Framework Core (EF Core), developers often notice that queries involving collection navigation properties (especially when using .Include() — generate an additional ORDER BY clause in the SQL output. This behaviour can be puzzling, particularly since the relationship keys are already available in the result set. This article explains why EF Core does this, demonstrates the behaviour in practice, and provides references for further reading.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example Model
&lt;/h4&gt;

&lt;p&gt;Consider the following simple domain model:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;public class Blog&lt;br&gt;
{&lt;br&gt;
    public int Id { get; set; }&lt;br&gt;
    public string Title { get; set; }&lt;br&gt;
    public List&amp;lt;Post&amp;gt; Posts { get; set; } = new();&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;public class Post&lt;br&gt;
{&lt;br&gt;
    public int Id { get; set; }&lt;br&gt;
    public string Content { get; set; }&lt;br&gt;
    public int BlogId { get; set; }&lt;br&gt;
    public Blog Blog { get; set; }&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  The Query
&lt;/h4&gt;

&lt;p&gt;A straightforward EF Core query to eagerly load related posts might look like this:&lt;br&gt;
&lt;code&gt;var blogs = context.Blogs&lt;br&gt;
    .Include(b =&amp;gt; b.Posts)&lt;br&gt;
    .ToList();&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  The Generated SQL
&lt;/h4&gt;

&lt;p&gt;When logging is enabled (via ToQueryString() or a database profiler), EF Core might generate a query similar to the following:&lt;br&gt;
&lt;code&gt;SELECT [b].[Id], [b].[Title],&lt;br&gt;
       [p].[Id], [p].[Content], [p].[BlogId]&lt;br&gt;
FROM [Blogs] AS [b]&lt;br&gt;
LEFT JOIN [Posts] AS [p] ON [b].[Id] = [p].[BlogId]&lt;br&gt;
ORDER BY [b].[Id]&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why EF Core Adds ORDER BY
&lt;/h2&gt;

&lt;p&gt;At first glance, this extra ordering may appear unnecessary — after all, the BlogId field in the Posts table already indicates the relationship between posts and blogs. However, EF Core's query pipeline &lt;strong&gt;is not simply returning raw rows;&lt;/strong&gt; it is &lt;strong&gt;materialising an object graph&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When a &lt;em&gt;LEFT JOIN&lt;/em&gt; is performed for eager loading:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The result set is &lt;em&gt;flattened&lt;/em&gt; — each blog is repeated for each of its posts.&lt;/li&gt;
&lt;li&gt;EF Core must group dependent rows (Posts) under their principal (Blog) in memory.&lt;/li&gt;
&lt;li&gt;Without a guaranteed order, rows could arrive interleaved, requiring EF Core to maintain a more complex in-memory lookup (such as a dictionary) to correctly assign posts to blogs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By ordering the results by the primary key(s) of the principal entity (Blog.Id in this case), EF Core ensures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rows belonging to the same blog are contiguous in the result set.&lt;/li&gt;
&lt;li&gt;Materialisation is faster and requires less memory overhead.&lt;/li&gt;
&lt;li&gt;The grouping operation becomes a simple sequential process.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Without Ordering – Potential Issue
&lt;/h4&gt;

&lt;p&gt;Without ordering, the query result from the database could look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqx8gs5auc3bqe4a1ipo4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqx8gs5auc3bqe4a1ipo4.png" alt="Without ordering" width="800" height="236"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, EF Core would have to detect and match entities in a non-contiguous manner, increasing processing complexity.&lt;/p&gt;

&lt;h4&gt;
  
  
  With Ordering – Efficient Grouping
&lt;/h4&gt;

&lt;p&gt;With ordering by Blog.Id:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxhrsuktbxlmjr8bk80ef.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxhrsuktbxlmjr8bk80ef.png" alt="With ordering" width="800" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;EF Core can now process the result set sequentially, attaching posts to blogs without additional lookups.&lt;/p&gt;

&lt;h2&gt;
  
  
  Official Notes and References
&lt;/h2&gt;

&lt;p&gt;The EF Core team has acknowledged this behaviour in discussions and issue trackers:&lt;br&gt;
"The ORDER BY clause is added when materializing 1-to-many relations, so that the principal is grouped together while loading the dependent. Without this, rows can arrive in an arbitrary order..."&lt;br&gt;
&lt;a href="https://github.com/dotnet/efcore/issues/19571" rel="noopener noreferrer"&gt;— EF Core GitHub Issue #19571&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;p&gt;For deeper exploration of EF Core query behaviour and performance:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;"Entity Framework Core in Action"&lt;/strong&gt; – Jon P Smith&lt;br&gt;
Detailed coverage of loading strategies and query optimisation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;"Pro Entity Framework Core 7"&lt;/strong&gt; – Adam Freeman&lt;br&gt;
Includes explanations of query translation, eager loading, and materialisation performance considerations.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;ORDER BY&lt;/strong&gt; clause added by EF Core during eager loading of collection navigation properties is not an arbitrary decision. It is a deliberate design choice aimed at optimising the materialisation process by ensuring contiguous grouping of related data. While it may seem redundant when relationship keys are present, this approach simplifies EF Core's internal processing and can improve performance for large datasets.&lt;/p&gt;

</description>
      <category>efcore</category>
      <category>dotnet</category>
      <category>programming</category>
      <category>performance</category>
    </item>
  </channel>
</rss>
