Q&A on Entity Framework for Enterprise Applications with Ben Day
What do you do when your simple Entity Framework app isn't so simple anymore and entity relationships are getting complex and you're getting worried about performance problems? Can you even use EF in a high-performance, scalable web application?
Well, you certainly can. Microsoft's flagship open source, cross-platform object-relational mapper (O/RM) is more than up to the task with tools like WebApplicationFactory and more. The company just shipped Entity Framework Core 7 (EF7) Release Candidate 1, polishing things up for an early November debut. It features new goodies ranging from new interceptors to customizable database-first scaffolding templates, all while boasting significantly better performance.
And to show you how to use the shiny new toys, expert developer/author/trainer Ben Day will present an in-person session titled "Entity Framework Core for Enterprise Applications" at next month's big Live!360 tech conference being held in Orlando Nov. 13-18.
In the 75-minute presentation, Day, a consultant and trainer specializing in software best practices using Scrum with Microsoft's DevOps tools, will go beyond the simple Code First EF cases and get into more complex class designs and relationships. He will address sticky issues around lazy-loading, concurrency, cascading deletes, occasional connectedness and performance testing. He will also make time to talk strategy for DevOps, stored procedures, unit testing and incremental deployment, specifically teaching attendees:
- What is WebApplicationFactory and how does it help to test ASP.NET Core code?
- How to write tests for WebAPI Controllers and MVC Controllers.
- How to access ASP.NET Core app's dependency injection configuration at runtime ... and why would you care.
We caught up with Day in advance of next month's presentation to learn more about building more complex data-based applications for the enterprise in a short Q&A.
VisualStudioMagazine: How Do You Get Started in Using Entity Framework for a High-Performance, Scalable, Enterprise Web Application?
Day: Well, the gist of where I'd start is less about scalability and more about maintainability. To me, an "enterprise application" implies something big, complex and expensive to write that a company (an enterprise) would expect to live on for a long time and grow and change with the long-term needs of the business. In order for that application to have a long life and in order for the developers to not loathe doing maintenance on this app, they really need to think about how to build something that's maintainable.
Things that I'd be thinking about would be the ability to easily write great unit tests (automated tests). In order to do that, you'll need to think about how you model your application dependencies and keeping a clean separation of concerns. When I say "separation of concerns" and "application dependencies," I'm thinking about making sure that certain types of logic are separated from each other -- such as separating the UI code from the domain model code from the data-access code.
"At the end of all this, if you do it well, you'll actually have hidden the existence of Entity Framework from the rest of your application. This has a nice side benefit of protecting yourself from performance problems."
Benjamin Day, Author, Trainer, Developer
At the end of all this, if you do it well, you'll actually have hidden the existence of Entity Framework from the rest of your application. This has a nice side benefit of protecting yourself from performance problems. Think of it like an insurance policy for performance problems. If you followed good patterns for hiding/encapsulating your Entity Framework data access logic and entities from the rest of your app -- if it turns out that you find a performance problem that you simply can not fix in Entity Framework -- you can simply swap that bit of data access code with something else.
I guess I'd say that while I love Entity Framework, I never want to code myself into a place where I'm locked in and don't have options. I'd say I've got a healthy dose of skepticism towards any third-party framework -- I always want to preserve some options.
What Holds Developers Back from Going Beyond Simple Code First Entity Framework Cases and Getting into More Complex Class Designs and Relationships?
Do you want the real answer or the snarky answer? 🙂 The snarky answer is "good sense and an instinct for self-preservation." The less-snarky answer is that I'm not sure that getting into really complex designs and relationships is that great of an idea.
I learned this lesson what feels like a hundred years ago when I used to do a lot of work with NHibernate. NHibernate is another object-relational mapper (ORM) that pre-dated Entity Framework. Anyway, I worked on a project where I basically used all the advanced mapping features of NHibernate to pretty much exactly map my domain model into the relational database. The domain model (aka the object model) was beautiful and the database schema was amazing ... but when we started running the application, the performance was terrible because of all the JOINs that were required between tables.
In my talk, I call this the Chris Rock Principle. Paraphrasing and cleaning up the stand-up quote for a family-friendly audience -- "you can drive with your feet ... it's doesn't mean it's a good idea." Objects in C# don't have the same shape as data in a relational database. That's the Object-Relational Impedance Mismatch Problem. It might be the same data but how it's stored, represented and interacted with is completely different.
When I'm designing my classes and mappings, I really try to keep it as simple as possible. I also think a lot about denormalization because fully normalized relational data doesn't always scale the way you'd expect.
Bottom line with regard to complex mappings: Just because you can do something, doesn't mean you should.
The EF6 Dev Team Has Lately Focused on Getting Performance up to Par with Raw SQL Queries Using Dapper. Have You been Able to Play Around with the Previews to See How Performance Is Coming Along?
I haven't done much analysis with this. To be honest, I don't worry that much about performance in Entity Framework. I do worry about giving myself options in my code and architecture so that if I run into an insurmountable performance problem with EF that I have a way to drop in my own raw SQL code.
A lot of times the places that I have performance problems are also the places where my LINQ queries against my DbContext start getting hairy -- lots of JOINs, tons of Include() and ThenInclude() statements. When that starts looking tricky, that's probably also where EF is going to start having problems. Usually, I find that the answer to those problems is just to drop in a stored procedure call. EF has done a really nice job making that (calling stored procedures from EF) a lot easier.
But back to my lack of concern about performance for a second. When I'm writing an application that is going to be deployed to Azure, I think that the scaling is just different than what we worried about even 10 years ago. You're doing a lot more "scaling out" (more instances of your app) rather than "scaling up" (bigger hardware for your app). Along with that, the way we store our data is different now -- we think a lot more about partitioning for performance -- basically giving the storage engine hints about how to find and store our data. I feel like we just didn't think about that kind of performance "stuff" 10+ years ago when we were writing lots of on-prem systems.
What Are Primary Considerations in Writing Tests for WebAPI Controllers and MVC Controllers?
Dependency Injection, Dependency Injection and Dependency Injection. It's all about separating out your dependencies. Does your Controller need to talk to the database? Well, please don't "new up" an instance of DbContext! Create an interface that represents what you want to do in that database and then pass that in to the constructor for the Controller. That's going to let you mock your database interactions when testing. Put another way, when you're writing/running tests, you won't test against your real database or even Entity Framework -- you'll test the logic of your Controller by itself in isolation from the database dependencies.
It's a little harder to code when you're getting started but once you figure it out, it makes writing unit tests SO MUCH EASIER.
I cover a lot of this in my Pluralsight course on unit testability, Architecting an ASP.NET Core MVC Application for Unit Testability.
Can You Briefly Explain the WebApplicationFactory?
WebApplicationFactory<T> is a really cool class in .NET Core that helps you test your ASP.NET MVC and WebAPI apps. When you test using WebApplicationFactory, it starts your application in memory with some special networking magic that I won't pretend to understand. It saves you from having to deploy your app to a server. You pretty much just say "run this" and your app spins up and spins down automatically. It's one of the most underappreciated features in .NET Core!
David Ramel is an editor and writer for Converge360.