SqlConnection, SqlCommand, SqlDataReader, and SqlDataAdapter are classes we were very familiar with in 2008. If you wanted to write a database query, you were probably using a combination of these classes. Things changed in 2008 with the release of .NET 3.5 SP1, giving .NET a Microsoft-provided Object-Relational Mapping (ORM).
A lack of ORM was becoming a bit of a problem back in 2008. At the time, RubyOnRails was the hot framework, and its ORM ActiveRecord was significantly simpler than the soup of “Sql” classes required by .NET.
Another big issue with the way we were structuring queries back in 2008 was the use of magic strings. Nothing was strongly typed. The advent of LINQ before this enabled the creation of strongly-typed queries within C# that could then be translated into SQL queries that ran on the server.
Entity Framework (EF) was a major improvement to the day-to-day life of .NET developers. And it has continued to improve. The very early version of EF had many problems, the primary being performance. It was common for people to avoid using EF because of its performance issues. But Microsoft has continued to improve the performance of EF, and today I see no reason to avoid using EF for most CRUD screens or basic queries.
One of the wonderful things about EF is it works so seamlessly with LINQ that it almost feels like writing SQL queries. It made SQL almost feel like part of C#, instead of something wholly different. The query below almost feels like a SQL query.
EF enables us to write better and more concise .NET code. This is a huge win for all of us, and I doubt many would want to go back.
.NET Framework 2.0 (Generics, Partial Classes, Nullable Types, Anonymous Methods)
.NET Framework 3.0/3.5 (WPF, WF, WCF, Auto-Implemented Properties)
.NET Framework 3.0 (LINQ)
.NET Framework 3.5 SP1 (ADO.NET Entity Framework)
.NET Framework 4.0 (Parallel, Dynamic)
.NET Framework 4.5 (Async)
.NET Core 2.0/2.1
.NET Core 3.0/3.1
.NET Core 5