Quick answer: Entity Framework Core (EF Core) is Microsoft’s object-relational mapper for .NET. It lets developers work with database tables as C# classes and write queries in LINQ instead of hand-written SQL. For most line-of-business apps (portals, admin tools, internal systems) it saves development time and keeps code consistent. The tradeoffs are performance surprises if queries are written carelessly, less control over the exact SQL, and a learning curve around change tracking and migrations. Many teams use EF Core for everyday work and drop to raw SQL or a micro ORM such as Dapper for the few queries that need it.
What Entity Framework Core actually does
Most business applications store data in a relational database such as SQL Server, PostgreSQL or SQLite. The application code, though, works with objects: a Customer, an Order, an Invoice. Something has to translate between the two.
EF Core handles that translation. Developers define classes for their data and a DbContext that describes how those classes map to tables. EF Core then:
- Turns LINQ queries into SQL and runs them
- Converts the results back into objects
- Tracks changes to those objects and writes updates in a single
SaveChangescall - Manages schema changes through migrations
The current long-term support release is EF Core 3.1, which runs on .NET Core 3.1. EF Core 5.0 is in preview, so production apps today should plan around 3.1 and treat new preview features as “coming later.”
Where EF Core works well
Faster development for typical data access
The biggest benefit is speed. Create, read, update and delete operations, which make up most of a business app, take far less code than writing SQL and mapping results by hand. That means features ship sooner and there is less boilerplate to maintain.
Strongly typed queries
Because queries are written in C#, the compiler catches many mistakes before the code runs. Rename a property and the build tells you every query that needs attention. With SQL in strings, you find out at runtime, sometimes in production.
Migrations keep the schema in step with the code
EF Core migrations record each change to the data model as a small code file. Developers can apply them locally, in testing and in production in the same order. This makes database changes reviewable and repeatable, which helps when several developers work on the same app. It fits well with a proper staging and deployment process.
Safer by default against SQL injection
LINQ queries are parameterized automatically. Even raw SQL methods such as FromSqlInterpolated turn interpolated values into parameters. That does not make an app secure on its own, but it removes one of the most common mistakes. Our explainer on SQL injection covers why this matters.
Works across databases
EF Core has providers for SQL Server, SQLite, PostgreSQL (through Npgsql), MySQL and others, plus an in-memory provider for some kinds of testing. Switching databases is rarely trivial, but much of the data access code carries over.
Good fit with ASP.NET Core
EF Core plugs into ASP.NET Core’s dependency injection, configuration and logging. If you are building services with ASP.NET Core Web API, EF Core is the natural default for the data layer.
Where EF Core causes trouble
Performance surprises
EF Core makes it easy to write a query that looks harmless but does a lot of work. Common problems:
- N+1 queries, where code loads a list and then triggers a separate query for each item (often through lazy loading)
- Loading whole entities when you only need two or three columns
- Change tracking overhead on read-only queries that will never be saved
- Large joins from
Include. In EF Core 3.x, a query that includes several collections is sent as one SQL statement. With many related rows, that can return a huge, repetitive result set.
These are all fixable. Projecting into small classes with Select, using AsNoTracking for read-only queries, and being deliberate about what you include go a long way. But someone on the team has to understand what SQL is being generated.
Less control over the SQL
For complex reports, heavy aggregation or carefully tuned queries, the SQL EF Core generates may not be what a database specialist would write. You can log the generated SQL and fall back to raw SQL or stored procedures, but at that point you are partly outside the ORM. If database speed is already a concern, read our notes on SQL Server performance tuning for .NET apps.
Breaking changes between major versions
EF Core 3.0 changed how LINQ is translated. Earlier versions quietly ran parts of a query in memory when they could not be translated to SQL. From 3.0 onward, EF Core throws an error instead. That is the right behavior (silent in-memory evaluation hid serious performance problems), but it meant real work for teams upgrading from 2.x.
Feature gaps in 3.1
Some modeling features developers expect are not in EF Core 3.1:
- Many-to-many relationships need an explicit join entity
- Table-per-type inheritance is not supported (table-per-hierarchy is)
- Bulk updates and deletes still load and track entities unless you use raw SQL or a third-party extension
Several of these are planned for EF Core 5.0, but you should not design a production app around preview features.
A learning curve
Change tracking, entity states, DbContext lifetimes and migrations take time to understand. Teams new to EF Core sometimes keep a DbContext alive too long, share it across threads, or misunderstand when changes are saved. These mistakes show up as odd bugs rather than clear errors.
EF Core vs the alternatives
EF Core vs Entity Framework 6
Entity Framework 6 is the older, mature ORM from the .NET Framework era. EF 6.4 can run on .NET Core 3.x, which helps when moving existing apps. For new development, EF Core is where Microsoft is putting its effort. If you are planning a wider move, our guide to moving from .NET Framework to .NET Core covers the bigger decision.
EF Core vs Dapper
Dapper is a lightweight “micro ORM.” You write the SQL yourself and Dapper maps the results to objects quickly. It is a strong choice for read-heavy endpoints and reports where you want full control. It does not do change tracking or migrations, so you write more code for inserts, updates and schema changes.
Many teams use both: EF Core for most of the app, Dapper for a handful of performance-sensitive queries. They can share the same database connection.
EF Core vs raw ADO.NET or stored procedures
Hand-written SQL and stored procedures give maximum control and can be very fast. The cost is more code, more manual mapping and more places for bugs. For a large app with a dedicated database team, this can still make sense. For a small team building a business app, it usually slows delivery.
When EF Core is a good choice
EF Core tends to fit when:
- The app is mainly forms, lists, dashboards and workflows over relational data
- The team is small and delivery speed matters
- The data model will change over time and you want migrations
- Most queries are straightforward filters, sorts and joins
When to think twice
Consider other approaches, or a mixed approach, when:
- The app is mostly heavy reporting or analytics over large tables
- You need very tight control over query plans and SQL
- An existing database is full of stored procedures and complex views that the business depends on
- The data is not really relational and a document store would fit better (see our comparison of SQL and NoSQL)
Practical tips if you choose EF Core
- Log generated SQL during development and review it for slow pages.
- Use
AsNoTrackingfor read-only queries. - Project into small view models with
Selectinstead of loading whole entities. - Avoid lazy loading by default; load related data on purpose.
- Keep
DbContextshort-lived, usually one per web request. - Review migrations in code review before they reach production.
- Test against a real database engine, not only the in-memory provider, since it does not behave like a relational database in every case.
FAQ
Is Entity Framework Core fast enough for production apps?
Yes, for most business applications. Performance problems usually come from how queries are written, not from EF Core itself. For the few queries that need more speed, raw SQL or Dapper can sit alongside it.
Should we upgrade from EF Core 2.x to 3.1?
Generally yes, since 3.1 is the long-term support release. Budget time to fix queries that relied on in-memory evaluation, because those now throw errors.
Can EF Core work with an existing database?
Yes. EF Core can scaffold classes from an existing schema, and you can map entities to tables and columns that do not follow its default naming rules.
Is EF Core only for SQL Server?
No. It supports several databases through providers, including PostgreSQL, MySQL and SQLite.
Choosing the right data layer
Entity Framework Core is a sensible default for most .NET business apps: it speeds up development, keeps queries type-safe and handles schema changes cleanly. The key is knowing its limits and having someone on the team who reads the SQL it produces. If you are planning a new .NET application or rescuing a slow one, our custom development team can help you pick the right approach.