Entity Framework Core 5.0 - Plan Quick Review

Introduction

 
The Plan for Entity Framework Core 5.0 is already announced, but It is important to know that this is not the final plan, and this agenda may vary.
 
 
One of the important notes about is that EF Core 5.0 does not support .NET Framework. So, I recommend you do avoid using .Net Framework for the new projects. .NET Framework should only be used in the legacy projects if required. The other important news is that EF Core 5.0 will contain some breaking changes, especially around TPT support.
 
Proposals and Bug Fixes
 

Many-to-many navigation properties (a.k.a "skip navigations")

 
This feature helps to avoid the overhead in the Many-to-many navigation properties the syntax.
 
Example
  1. public class Customer      
  2. {      
  3.   /// <summary>Gets or sets the customer identifier.</summary>      
  4.   /// <value>The product inventory identifier.</value>      
  5.   public long CustomerId { get; set; }      
  6.        
  7.   /// <summary>Gets or sets the name.</summary>      
  8.   /// <value>The name.</value>      
  9.   public string Name { get; set; }      
  10.        
  11.   /// <summary>  Gets or sets the address. </summary>      
  12.   /// <value> The address. </value>      
  13.   public string Address { get; set; }      
  14.        
  15.   /// <summary>Gets or sets the create date.</summary>      
  16.   /// <value>The create date.</value>      
  17.   public DateTimeOffset CreateDate { get; set; }      
  18.        
  19.   /// <summary> Gets or sets the customerProducts. </summary>      
  20.   /// <value> The products. </value>      
  21.   public ICollection<CustomerProduct> CustomerProducts { get; set; }      
  22.        
  23. }      
  24.        
  25. public class Product      
  26. {      
  27.   /// <summary>Gets or sets the product  identifier.</summary>      
  28.   /// <value>The product inventory identifier.</value>      
  29.   public long ProductId { get; set; }      
  30.        
  31.   /// <summary>Gets or sets the name.</summary>      
  32.   /// <value>The name.</value>      
  33.   public string Name { get; set; }      
  34.        
  35.   /// <summary>Gets or sets the description.</summary>      
  36.   /// <value>The description.</value>      
  37.   public string Description { get; set; }      
  38.        
  39.   /// <summary>Gets or sets the create date.</summary>      
  40.   /// <value>The create date.</value>      
  41.   public DateTimeOffset CreateDate { get; set; }      
  42.        
  43.   /// <summary> Gets or sets the customerProducts. </summary>      
  44.   /// <value> The customers. </value>      
  45.   public ICollection<CustomerProduct> CustomerProducts { get; set; }      
  46. }     
    Many-to-many navigation properties In EF Core 3
    1. var customers    
    2.   = shopDbContext.Customers    
    3.     .Include(e => e.CustomerProducts)    
    4.     .ThenInclude(e => e.Product)    
    5.     .ToList();    
    6.          
    7. var playStationFiveCustomers    
    8.   = shopDbContext.Customers    
    9.     .Where(e => e.CustomerProducts.Select(customerProduct => customerProduct.Product.Name)    
    10.     .Contains("PlayStation 5")).ToList();    
      The proposal to solve the problem:
      1. public class Customer    
      2. {    
      3.   /// <summary>Gets or sets the customer identifier.</summary>    
      4.   /// <value>The product inventory identifier.</value>    
      5.   public long CustomerId { get; set; }    
      6.          
      7.   /// <summary>Gets or sets the name.</summary>    
      8.   /// <value>The name.</value>    
      9.   public string Name { get; set; }    
      10.        
      11.   /// <summary>  Gets or sets the address. </summary>    
      12.   /// <value> The address. </value>    
      13.   public string Address { get; set; }    
      14.         
      15.   /// <summary>Gets or sets the create date.</summary>    
      16.   /// <value>The create date.</value>    
      17.   public DateTimeOffset CreateDate { get; set; }    
      18.       
      19.   /// <summary> Gets or sets the products. </summary>    
      20.   /// <value> The product. </value>    
      21.   public ICollection<Product> Products { get; set; } // Help you to Skips over CustomerProduct to Product    
      22.          
      23.   /// <summary> Gets or sets the customerProducts. </summary>    
      24.   /// <value> The products. </value>    
      25.   public ICollection<CustomerProduct> CustomerProducts { get; set; }    
      26.         
      27.  }    
      28. public class Product    
      29. {    
      30.   /// <summary>Gets or sets the product  identifier.</summary>    
      31.   /// <value>The product inventory identifier.</value>    
      32.   public long ProductId { get; set; }    
      33.          
      34.   /// <summary>Gets or sets the name.</summary>    
      35.  /// <value>The name.</value>    
      36.  public string Name { get; set; }    
      37.          
      38.   /// <summary>Gets or sets the description.</summary>    
      39.   /// <value>The description.</value>    
      40.   public string Description { get; set; }    
      41.          
      42.   /// <summary>Gets or sets the create date.</summary>    
      43.   /// <value>The create date.</value>    
      44.   public DateTimeOffset CreateDate { get; set; }    
      45.          
      46.   /// <summary> Gets or sets the customers. </summary>    
      47.   /// <value> The customers. </value>    
      48.  public ICollection<Customer> Customers { get; set; } // Help you to skips over CustomerProduct to Customer    
      49.          
      50.   /// <summary> Gets or sets the customerProducts. </summary>    
      51.   /// <value> The customers. </value>    
      52.   public ICollection<CustomerProduct> CustomerProducts { get; set; }    
      53. }   
        Many-to-many navigation properties In EF Core 5.0
        1. var postsAndTags     
        2.   = shopDbContext.Customers    
        3.     .Include(e => e.Products)    
        4.     .ToList();    
        5.        
        6. var post    
        7.   = shopDbContext.Customers    
        8.     .Where(e => e.Products.Select(e => e.Name).Contains("PlayStation 5")).ToList();   

          Table-per-type (TPT) inheritance mapping

           
          Officially, EF Core is not supporting Table-per-Type (TPT), because of TPT can easily be misused and causes performance issues. DDD developers working differently. They are creating domain models in Bounded Contexts. So that means they do not have this one big monolithic domain model and a lot of joins that are coming from the Includes. TPT will add some overhead and joins to the queries, but the DDD developers can handle this problem effectively. For this reason, a lot of DDD developers found that TPT is very useful, and that makes the customization very easy and flexible. EF Core Team has decided to add this feature to EF Core 5.0.
           
          "Even if TPT is considered slow, it is a boon for many real-world business scenarios. If implemented properly and well thought of, TPT is not slow for a given need in most of the cases".
           
          If possible, optimization can be done to TPT.
           
          But its a very important feature for EF to be accepted for developing DDD applications.
           
          The other method, Composition over Inheritance does not look viable since we cannot use interface property to create our model. Binding to a concrete type takes away the flexibility to customize the models. TPT makes the customization very easy and flexible.
           
          We are doing TPT because it is both a highly requested feature (~254 votes; 3rd overall) and because it requires some low-level changes that we feel are appropriate for the foundational nature of the overall .NET 5 plan. We expect this to result in breaking changes for database providers, although these should be much less severe than the changes required for 3.0".
           

          Filtered Include

           
          Global query filters are useful in many use cases, but sometimes you need more control about the filter.
           
          This feature to specify allows filters on Include on a per-query basis.
           
          “Filtered Include is a highly-requested feature (~317 votes; 2nd overall) that isn't a huge amount of work, and that we believe will unblock or make easier many scenarios that currently require model-level filters or more complex queries”.
           
          Currently, Doing a .Where() inside a .Include() is allowed (by the syntax, it fails in execution):
          1. var deletedCustomers = shopDbContext    
          2.            .Barcodes    
          3.            .Include(t => t.Products.Where(c => c.IsSoftDeleted))    
          4.            .ToList();   
            With the following by execution error:
             
            System.InvalidOperationException- 'Lambda expression used inside Include is not valid.'
             
            According to the proposal, if you then follow that up with ThenInclude(), like so:
            1. deletedCustomers = shopDbContext    
            2.      .Barcodes    
            3.      .Include(t => t.Products.Where(c => c.IsSoftDeleted))    
            4.      .ThenInclude(r => r.Barcode)    
            5.      .ToList();   
              You should get the error-
               
              'IEnumerable' does not contain a definition for 'User' and no extension method 'User' accepting a first argument of type 'IEnumerable' could be found (are you missing a using directive or an assembly reference?)”
               
              If this feature will be added to EF Core 5.0 d then the above syntax (or something similar) is allowed in EF Core 5.0.
               

              Rationalize ToTable, ToQuery, ToView, FromSql,etc.

               
              The following code
              1. /// <summary>    
              2. /// The barcode class.    
              3. /// </summary>    
              4. public class Barcode2    
              5. {    
              6.    /// <summary> Gets or sets the barcode text. </summary>    
              7.    /// <value> The barcode text. </value>    
              8.    public string BarcodeText { get; set; }    
              9. }   
              1. public DbSet<Barcode2> Barcodes2 { get; set; }    
              2. …    
              3. …    
              4.         
              5. modelBuilder.Entity<Barcode2>().HasNoKey();    
              6. modelBuilder.Entity<Barcode2>().ToTable("BarcodeTable");    
              7. modelBuilder.Entity<Barcode2>().ToQuery(() => this.Barcodes2.OrderBy(p => p.BarcodeText));   
                This exception was originally thrown at this call stack
                1. Microsoft.Data.SqlClient.SqlException: 'Invalid object name 'BarcodeTable'.':     
                2. This exception was originally thrown at this call stack:    
                3.     [External Code]    
                4.     EntityFrameworkCore5Demo.Program.Main(string[]) in Program.cs   
                  That because currently, if you call two methods like ToTable and ToQuery on the same entity type isn't clear.
                   
                  When this feature is done, then the ideal output for the above definition for the following call context.People.ToList() should mean that generate the following SQL:
                  1. SELECT [b]    
                  2. FROM [BarcodeTable] AS [b]    
                  3. ORDER BY [b].[ BarcodeText]   
                    More information
                     
                     

                    General query enhancements

                     
                    EF-Team isn't planning on making significant query changes, outside those needed to support TPT and skip navigation properties. However, there is still significant work needed to fix some technical debt left over from the 3.0 overhaul. They are plan to fix many bugs and implement small enhancements to further improve the overall query experience.
                     
                     

                    Migrations and deployment experience

                     
                    Database Migration at databases at application startup time can cause a lot of problems; that why the EF-Core Team recommending you to avoid that. The alternative solution is migrating the database at the deployment time. EF-Core team pans to improve the migrations tool/command line so that you can easily migrate you’re the database at deployment time.
                     
                    Problems by Database Migration at application startup
                    • Multiple threads/processes/servers may attempt to migrate the database concurrently
                    • Applications may try to access inconsistent state while this is happening
                    • Usually, the database permissions to modify the schema should not be granted for application execution
                    • It’s hard to revert back to a clean state if something goes wrong
                    Improvements to migrate the database at deployment time
                    • Work on Linux, Mac, and Windows
                    • Be a good experience on the command line
                    • Support scenarios with containers
                    • Work with commonly used real-world deployment tools/flows
                    •  Integrate into at least Visual Studio
                    This an "epic" issue for the theme of improving the Migrations and deployment experience. Specific pieces of work will be tracked by linked issues.
                     
                     

                    EF Core platforms experience

                     
                    EF Core team plans to more tutorials and documentation of using EF Core 5.0 with:
                    • Blazor
                    • Xamarin, including using the AOT/linker story
                    • WinForms/WPF/WinUI and possibly other U.I. frameworks
                    Small improvements in the specific areas:
                    • Deployment, including the experience for using EF tooling such as for Migrations 
                    • Application models, including Xamarin and Blazor, and probably others
                    • SQLite experiences, including the spatial experience and table rebuilds
                    • AOT and linking experiences
                    • Diagnostics integration, including perf counters

                    Performance

                     
                    EF Core team plans to improve the suite of performance benchmarks and make directed performance improvements to the runtime. In addition, they plan to complete the new ADO.NET batching API, which was prototyped during the 3.0 release cycle.
                     
                    More information
                     
                     

                    Document EF Core architecture and internal technical details

                     
                    EF Core team plans to make the internal stuff EF-Core (code and Architecture) more transparent and well documented
                     
                    This can be useful to anyone using EF Core, but the primary motivation is to make it easier for external people to:
                    • Contribute to the EF Core code
                    • Create database providers
                    • Build other extensions

                    Microsoft.Data.Sqlite documentation

                     
                    EF Core Team also owns the Microsoft.Data.Sqlite ADO.NET provider and they plass to fully document this provider as part of the 5.0 release.
                     
                     

                    General documentation

                     
                    Updating documentation for the 3.0 and 3.1 releases and they are also working on:
                    • An overhaul of the getting started docs to make them more approachable/easier to follow
                    • Reorganization of docs to make things easier to find and to add cross-references
                    • Adding more details and clarifications to existing docs
                    •  Updating the samples and adding more examples
                     

                    Fixing bugs

                     
                     
                    Not all of these will need to be fixed in 5.0. As a rough estimate they plan to fix an additional 150 issues in the 5.0-time frame.
                     

                    Small enhancements

                     
                     
                    In addition to the bigger features outlined above, we also have many smaller improvements scheduled for 5.0 to fix "paper-cuts". Note that many of these enhancements are also covered by the more general themes outlined above.
                     

                    Finally

                     
                     
                    These are bug fixes and enhancements that are not currently scheduled for the 5.0 release, but they will look at as stretch goals depending on the progress made on the work above.
                     
                    In addition, they always consider the most voted issues when planning.