Our application has been around over five years. When it was first designed, the architects chose to use the Enterprise Library from Microsoft combined with stored procedures in Oracle. It was a formalized codebase based on the Patterns and Practices from Microsoft Research.

Time has passed and we needed to centralize the data access in such a way as to allow for the addition of a mobile application. We decided to use Microsoft ADO.NET Core Web Api as the middle tier and re-design the back-end access strategy (replacing Enterprise Library).

I got busy designing and developing the Web Api (which we refer to as "wapi") and the other architect got busy developing a repository pattern framework around Entity Framework 6 (EF Core didn't have a way to interact with Oracle, yet, so we couldn't use it).

We completed the two parts of the new architecture and put it into production in July. A few months later, that architect got another job offer and left, leaving behind the repository wrapper that only he understood. Another developer on the team managed to figure out how to make it work, but we found that our 1 week sprints were taking over 1 month due to the complexity of the framework and the "tribal knowledge" required to make it work.

In short, our database is designed differently than most databases that Entity Framework was designed to handle. We never do a direct Update to a record. We insert a new record and set the inactive date of the existing record to the moment that the change was made. We have an entirely historical database where nothing is deleted or truly updated. That required some tricks with the change tracker and some serious hacks to the way that Entity Framework operated.

We also have ~50+ pivot tables that connect master/detail tables to keep this historical record keeping manageable. The repository was well-written and did its job well. However, we found that performance was poor and debugging was impossible. We were using composed queries and LinqKit to reuse some of our queries. Tracking down performance problems became a nightmare. The initial development went as well as could be expected, but maintenance was extremely difficult. Our DbContext strategy was flawed due to design decisions of the system.

We found that our lesser experienced developers were struggling with understanding how all of the pieces fit together. We had many custom in-house NuGet packages for our libraries and had many layers of abstraction. Too many.

After a few weeks of analysis, we decided that going backwards in time to a somewhat less civilized time would be the answer. We decided to stop using Entity Framework and use "raw" ADO.NET to access stored procedures mapped to DTOs. We weren't comfortable having our queries compiled into the language as LINQ expressions. Keeping them in the database as stored procedures would keep our options free for the future when C# and .NET are no longer the coolness.

While our newest solution is far from architecturally cool, we think it will be easier for the lesser experienced (and new) developers to work with. We are in a market that doesn't have much IT talent. We have to be happy with what we get and do our best to produce quality software with the resources at hand.