What’s in 1.1 Preview 1
The 1.1 release is focused on addressing issues that prevent folks from adopting EF Core. This includes fixing bugs and adding some of the critical features that are not yet implemented in EF Core. While Microsoft’ve made some good progress on this, Microsoft do want to acknowledge that EF Core still isn’t going to be the right choice for everyone. For more detailed info of what is implemented, see our EF Core and EF6.x comparison.
Improved LINQ translation
In the 1.1 release Microsoft have made good progress improving the EF Core LINQ provider. This enables more queries to successfully execute, with more logic being evaluated in the database (rather than in memory).
DbSet.Find
DbSet.Find(…) is an API that is present in EF6.x and has been one of the more common requests for EF Core. It allows you to easily query for an entity based on its primary key value. If the entity is already loaded into the context, then it is returned without querying the database.
using (var db = new BloggingContext()) { var blog = db.Blogs.Find(1); }
Mapping to fields
The new HasField(…) method in the fluent API allows you to configure a backing field for a property. This is most commonly done when a property does not have a setter.
public class BloggingContext : DbContext { ... protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .Property(b => b.Url) .HasField("_theUrl"); } }
By default, EF will use the field when constructing instances of your entity during a query, or when it can’t use the property (i.e. it needs to set the value but there is no property setter). You can change this via the new UsePropertyAccessMode(…) API.
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .Property(b => b.Url) .HasField("_theUrl") .UsePropertyAccessMode(PropertyAccessMode.Field); }
You can also create a property in your model that does not have a corresponding property in the entity class, but uses a field to store the data in the entity. This is different from Shadow Properties, where the data is stored in the change tracker. This would typically be used if the entity class uses methods to get/set values.
You can give EF the name of the field in the Property(…) API. If there is no property with the given name, then EF will look for a field.
public class BloggingContext : DbContext { ... protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .Property("_theUrl"); } }
You can also choose to give the property a name, other than the field name. This name is then used when creating the model, most notably it will be used for the column name that is mapped to in the database.
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .Property<string>("Url") .HasField("_theUrl"); }
You can use the EF.Property(…) method to refer to these properties in a LINQ query.
var blogs = db.Blogs .OrderBy(b => EF.Property<string>(b, "Url")) .ToList();
Explicit Loading
Explicit loading allows you to load the contents of a navigation property for an entity that is tracked by the context.
using (var db = new BloggingContext()) { var blog = db.Blogs.Find(1); db.Entry(blog).Collection(b => b.Posts).Load(); db.Entry(blog).Reference(b => b.Author).Load(); }
Additional EntityEntry APIs from EF6.x
Microsoft’ve added the remaining EntityEntry APIs that were available in EF6.x. This includes Reload(), GetModifiedProperties(), GetDatabaseValues() etc. These APIs are most commonly accessed by calling the DbContext.Entry(object entity) method.
Connection resiliency
Connection resiliency automatically retries failed database commands. This release includes an execution strategy that is specifically tailored to SQL Server (including SQL Azure). This execution strategy is included in our SQL Server provider. It is aware of the exception types that can be retried and has sensible defaults for maximum retries, delay between retries, etc.
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer( "<connection string>", options => options.EnableRetryOnFailure()); }
Other database providers may choose to add retry strategies that are tailored to their database. There is also a mechanism to register a custom execution strategy of your own.
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseMyProvider( "<connection string>", options => options.ExecutionStrategy(...)); }
SQL Server memory-optimized table support
Memory-Optimized Tables are a feature of SQL Server. You can now specify that the table an entity is mapped to is memory-optimized. When using EF Core to create and maintain a database based on your model (either with migrations or Database.EnsureCreated), a memory-optimized table will be created for these entities.
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .ForSqlServerIsMemoryOptimized(); }
Simplified service replacement
In EF Core 1.0 it is possible to replace internal services that EF uses, but this is complicated and requires you to take control of the dependency injection container that EF uses. In 1.1 Microsoft have made this much simpler, with a ReplaceService(…) method that can be used when configuring the context.
public class BloggingContext : DbContext { ... protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { ... optionsBuilder.ReplaceService<SqlServerTypeMapper, MyCustomSqlServerTypeMapper>(); } }
What’s happening after 1.1 Preview 1
The stable 1.1 release will be available later this year. Microsoft aren’t planning any new features between preview1 and the stable release. Microsoft will just be working on fixing bugs that are reported.
No comments:
Write comments