Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News Entity Framework Core 2.0 Released to Heavy Criticism

Entity Framework Core 2.0 Released to Heavy Criticism

This item in japanese


Entity Framework has always had a mixed reputation, with some developers loving it while other compared it unfavorably to NHiberante, LINQ-to-SQL, and the various micro-ORMs. But the early impressions of EF Core have been particularly bad and continue to frustrate even those who appreciated the original Entity Framework.

SQL Generation

At the top of the list is the poor support for SQL generation. EF Core 2.0 still doesn’t support basic SQL constructs such as grouping. While it isn’t unusual for ORMs to not support advanced features such as Window Functions, the inability to handle “GROUP BY” is considered to be unacceptable by many developers.

According to the release notes, this version has “increased the number of patterns that can be translated to SQL, so many queries that triggered client-side evaluation in previous versions will no longer do it in 2.0”. However, they still haven’t documented what those patterns are so we recommend that developers carefully verify each query. Alternately, you can disable client-side evaluation.

Microsoft has indicated that grouping support is being planned for EF Core 2.1.

Complex Types

In Entity Framework you have the concept of Complex Types. Essentially these allow you to create a child object that is mapped to the same table as its parent. One use of a complex type would be to separate commonly used audit fields from the regular data fields.

EF Core doesn’t support complex types, but instead has “owned” or “child” types. Diego B Vega of Microsoft claims that “Owned types in EF Core 2.0 support a superset of the scenarios supported by complex types in previous versions of EF”. However, they have a different syntax and design so porting complicated models may require some research.

Lazy Loading

Lazy loading is considered to be a bad idea by many because it can lead to performance problems (e.g. 1+N queries) and runtime failures (e.g. disposed contexts). Nonetheless, it is a very popular feature in Entity Framework and some people think that no library can truly be called an ORM without it. Understandably, they are upset that lazy loading is being delayed until EF Core 2.1.

Rowan Miller of Microsoft did mention the possibility of creating your own lazy loading scheme in the meantime:

Just to add one data point to the discussion. Lazy Loading isn't going to be in 2.0 but we are adding some features that are groundwork for implementing it. The biggest one is Life Cycle Hooks, which combined with the EntityEntry APIs we added in 1.1, will allow a rudimentary roll-your-own lazy loading pattern.

Life cycle hooks for object materialization are currently marked as a “stretch goal” for EF Core 2.1.

Table Per Type

Table Per Type Inheritance (TPT) allows one logical record to be split over multiple database tables. In this design, an abstract base class represents one table. Then each subclass of that has its own table. This allows the application to see a logical view of the data while the database gets a more efficient design.

Unfortunately, TPT has a reputation for having significant performance problems in Entity Framework. Here is one complaint on User Voice:

For TPT inheritance, the more subclasses you add, the time it takes to generate SQL, and the complexity of the SQL query itself, become unmanageable. With a simple base class (5 or 6 fields), and around 30 simple subclasses (two or three fields a piece), it takes almost two minutes to generate the SQL (ObjectQuery.ToTraceString()) and execute it on the server. EF generates almost 8000 lines of SQL for a simple select query on the base class. This is because the SQL generated is a mess of crazy subselects, joins, and unions. Even with empty tables (so that a query would return no data), it takes that long to generate and execute the SQL.

Many of these issues have been fixed, but EF 6 is considered to be an obsolete library and no further work is planned for it.

TPT isn’t supported at all in EF Core. There is a backlog item for it, but no specific plans to implement it. This is a problem for developers currently using TPT in EF, as major changes are needed to work-around this issue.

Table per Concrete Class

A closely related feature to TPT is TPC or Table per Concrete Class. Like TPT, this uses inheritance in the application to simply class design. However, on the database side there is no table that directly represents the abstract base class. Rather, every concrete (i.e. non-abstract) subclass is fully represented by its own table that includes the columns from both the subclass itself and any inherited classes.

While also not supported by EF Core, there doesn’t seem to be a lot of call for TPC. This is probably due to the fact that you can get the same net effect replacing the abstract base class with an abstract interface. The properties in the base class with have to be cut-and-pasted into each concrete class, but which is tedious but not difficult or error prone.

Stored Procedures

Another missing feature is full support for stored procedures. While they can be abused, stored procedures are one of the most powerful tools offered by relational database servers. In many scenarios, it is much more efficient to process all of the data in the database than it would be to try to transport the data over the network to the application. This is especially true when doing so would result in multiple round-trips while tables are locked inside a transaction.

This seems like it would be an easy feature to implement, as the SQL generation is quite simple. Even InfoQ’s demonstration of a micro ORM using the DLR included it using less than 200 lines of code. Yet it remains on the backlog with no indication as to when it will be implemented.

It may be a lower priority because work-arounds do exist. Anuraj P demonstrates how to call stored procedures in EF Core and some of the pain points such as the lack of named parameters.

Spatial Types

Working with spatial data is still not supported by EF Core. It is on the road map as a high priority item, but not tied to a specific release yet.

Not all news has been bad. In Part 2 of this series we’ll discuss the new features that did make it into EF Core 2.0.

Rate this Article


Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Community comments

  • sad

    by Mac Noodle,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    you have to feel sorry for people who can't or won't adventure outside the .NET world. Java has had wonderful ORM support for years. And IoC/DI too.

  • Important TPC consideration

    by Marcel Bradea,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Another really important point to add to the TPC points above is that referencing a type hierarchy from another type/table is easily doable in TPT since the base type contains the logical ID, while in TPT it would be hard to know which subclass the referencing type is pointing to. This is a pretty major limitation to TPC which could limit you severely in the future, even if your current requirements don't have an external entity being associated to one of your inherited types. Would be great to put this on people's maps since it's one of those little huge details when making architectural considerations.

    So essentially long story short: EF6 is still the definite way to go. Which means .NET Core is still not feasible in production. Which means no MacOS development and no microservices. Let's all keep our fingers crossed for these critical problems to be solved for 3.0 / 2019/2020 timeframe (*long sigh*...)

  • Re: Important TPC consideration

    by Jonathan Allen,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Entity Framework isn't the only option. If you are willing to give up deep object graphs, there are other ORMs that work in .NET Core that are both more flexible and better performing.

  • What about

    by Josh Yates,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    What's wrong with using dataadapters, datareaders, commandtypes, etc? It appears this would eliminate the layer EF creates on top of accessing the database and the developer would have more control with custom classes and objects. I'm not sure about performance and surely the experts at Microsoft know more about EF than my small developer brain or else EF would not exist. I've used both EF and in projects.

    I've created .net projects with uses cache management and With EF, that eliminates the need for cache management and I'm not stating this is bad, just a different approach. Plus, with Ntier architecture, EF eliminates the repository layer and can be called directly from the service layer or controller. Would this be a healthy SoC? Short cut?

  • Re: sad

    by Josh Yates,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    To speak in 2nd person and imply a "feel sorry" states nothing about your experience. Provide some details about your past tense statement of "has had wonderful ORM support." Does the support no longer exist?

  • Thanks You

    by Priya Kale,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Very helpful and Great information,
    I appreciate advise especially coming from a professional.
    Thanks again and keep up the great work!

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p