entity-framework/efcore-and-ef6/porting/port-detailed-cases.md
This document details some specific differences between EF6 and EF Core. Consult this guide when porting your code.
There are several differences between how EF6 connects to various data sources compared to EF Core. They are important to understand when you port your code.
UseSqlServer).EF6 supported custom ("lightweight") conventions and model conventions. The lightweight conventions are similar to EF Core's pre-convention model configuration. Other conventions are supported as part of model building.
EF6 runs conventions after the model is built. EF Core applies them as the model is being built. In EF Core, you can decouple model building from active sessions with a DbContext. It is possible to create a model initialized with the conventions.
EF Core does not support data validation and only uses data annotations for building the model and migrations. Most client libraries from web/MVC to WinForms and WPF provide a data validation implementation to use.
There are a few features in EF6 that don't exist yet in EF Core, but are on the product roadmap.
EF Core uses a DbContext instead of an ObjectContext. You will have to update code that uses IObjectContextAdapter. This was sometimes used for queries with PreserveChanges or OverwriteChanges merge option. For similar capabilities in EF Core, look into the Reload method.
There are many important differences between how models in EF6 and EF Core are designed. EF Core lacks full support for conditional mapping. It does not have model builder versions.
Other differences include:
In EF Core, Entity Types are discovered by the engine in three ways:
DbSet<TEntity> on your DbContext where TEntity is the type you wish to track.Set<TEntity> from somewhere in your code.Blog references a Post and Blog is discoverable, Post will be discovered as well)Assemblies are not scanned for derived types.
The .Map() extension in EF6 has been replaced with overloads and extension methods in EF Core. For example, you can use '.HasDiscriminator()` to configure table-per-hierarchy (TPH). See: Modeling Inheritance.
EF6 supported table-per-hierarchy (TPH), table-per-type (TPT) and table-per-concrete-class (TPC) and enabled hybrid mapping of different flavors at different levels of the hierarchy. EF Core will continue to require an inheritance chain to modeled one way (TPT or TPH) and the plan is to add support for TPC in EF7.
See: Modeling Inheritance.
EF6 supported index attributes on properties. In EF Core, they are applied at the type level which should make it easier for scenarios that require composite indexes. EF Core doesn't support composite keys with data annotations (i.e. using Order in ColumnAttribute together with KeyAttribute).
For more information, see: Indexes and constraints.
In EF Core model-building, IsRequired only configures the what is required on the principal end. HasForeignKey now configures the principal end. To port your code, it will be more straightforward to use .Navigation().IsRequired() instead. For example:
EF6:
modelBuilder.Entity<Instructor>()
.HasRequired(t => t.OfficeAssignment)
.WithRequiredPrincipal(t => t.Instructor);
EF Core 6:
modelBuilder.Entity<Instructor>()
.HasOne(t => t.OfficeAssignment)
.WithOne(t => t.Instructor)
.HasForeignKey<OfficeAssignment>();
modelBuilder.Entity<Instructor>()
.Navigation(t => t.OfficeAssignment)
.IsRequired();
modelBuilder.Entity<OfficeAssignment>()
.Navigation(t => t.Instructor)
.IsRequired();
By default everything is optional, so usually it's not necessary to call .IsRequired(false).
EF Core integrates with the third-party library community library NetTopologySuite to provide spatial support.
EF Core does not support independent associations (an EDM concept that allows the relationship between two entities to be defined independent from the entities themselves). A similar concept supported in EF Core is shadow properties.
EF Core does not support database initializers or automatic migrations. Although there is no migrate.exe in EF Core, you can produce migration bundles.
EF Core has no designer, no functionality to update the model from the database and no model-first flow. There is no reverse-engineering wizard and no built-in templates.
Although these features do not ship with EF Core, there are OSS community projects that provide additional tooling. Specifically, EF Core Power Tools provides:
.dacpac). Includes template-based code customizations.For a complete list of community tools and extensions, see: EF Core Tools and Extensions.
There are several differences between how EF6 and EF Core deal with change tracking. These are summarized in the following table:
| Feature | EF6 | EF Core |
|---|---|---|
| Entity State | Adds/attaches entire graph | Supports navigations to detached entities |
| Orphans | Preserved | Deleted |
| Disconnected, self-tracking entities | Supported | Not supported |
| Mutations | Performed on properties | Performed on backing fields* |
| Data-binding | .Local | .Local plus .ToObservableCollection or .ToBindingList |
| Change detection | Full graph | Per entity |
* By default, property notification will not be triggered in EF Core so it's important to configure notification entities.
Note that EF Core does not call change detection automatically as often as EF6.
EF Core introduces a detailed DebugView for the change tracker. To learn more, read Change Tracker Debugging.
EF6 has some query capabilities that do not exist in EF Core. These include:
EF6 has built-in support for lazy-loading proxies. This is an opt-in package for EF Core (see Lazy Loading of Related Data).
EF Core allows you to compose over raw SQL using FromSQL.