Entity framework is a great ORM provided by Microsoft. There are a ton of examples of how to get up and running with it really quickly. The only problem with all of them, is the get you off on the wrong foot.
In all of the EF example guides, the DbContext
class is typically deeply embedded into the core of your code. This of course is great for Entity framework because the effort to change will be next to impossible speaking from experience of course here.
Instead, by making some subtle changes we can integrate Entity framework in a separate layer in case at some later date you wish to replace it. Of course, you might never need to replace it, but following these simple techniques will allow better segregation of code and even provide simpler unit testing.
Before I begin, here are several different example articles that I was referring to on how to setup Entity framework in your project:
I dont want to re-invent the wheel here, nor do I want to write a lot of new code, so instead Im going to look at the first article (where a simple console application is created) and alter it to remove the DbContext
from the core Program.cs
file.
First, lets look at the full example code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;
namespace CodeFirstNewDatabaseSample
{
class Program
{
static void Main(string[] args)
{
using (var db = new BloggingContext())
{
Console.Write("Enter a name for a new Blog: ");
var name = Console.ReadLine();
var blog = new Blog { Name = name };
db.Blogs.Add(blog);
db.SaveChanges();
var query = from b in db.Blogs
orderby b.Name
select b;
Console.WriteLine("All blogs in the database:");
foreach (var item in query)
{
Console.WriteLine(item.Name);
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
}
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public virtual List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public virtual Blog Blog { get; set; }
}
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
}
}
This will look fairly straight-forward to anyone with some Entity framework experience. There are two Models
: Blog
and Post
. A new DbContext
is created called BloggingContext
. This class is instantiated inside the Main
function.
Three core functions are accessed about the DbContext
: Add
, SaveChanges
, and a query. If you were to attempt to replace Entity framework at this point, you need to messily change the core of your application. Might not seem so daunting in a 10 line function, but imagine 100s or even 1000s of lines of code
Instead of using the DbContext
inside our Main
function, lets create a new class called BlogRepo
. This class will contain the three same functions that are used in the current Main
function:
public class BlogRepo
{
private readonly BloggingContext _bloggingContext;
public BlogRepo(BloggingContext bloggingContext)
{
_bloggingContext = bloggingContext;
}
public void AddBlog(Blog blog)
{
_bloggingContext.Blogs.Add(blog);
}
public int SaveChanges()
{
return _bloggingContext.SaveChanges();
}
public IOrderedQueryable<Blog> GetAll()
{
return from b in _bloggingContext.Blogs
orderby b.Name
select b;
}
}
The above class has simply moved everything accessing the DbContext
class into the BlogRepo
class. Now some simple updates need to occur in the Main
function:
static void Main(string[] args)
{
using (var db = new BloggingContext())
{
BlogRepo repo = new BlogRepo(db);
Console.Write("Enter a name for a new Blog: ");
var name = Console.ReadLine();
var blog = new Blog { Name = name };
repo.AddBlog(blog);
repo.SaveChanges();
var query = repo.GetAll();
Console.WriteLine("All blogs in the database:");
foreach (var item in query)
{
Console.WriteLine(item.Name);
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
Just a few minor updates; a new BlogRepo
object was created; this was then used to add a new blog, save the blog, and finally return a list of all the blogs.
In the future, if we wish to replace Entity framework the core of the changes would need to happen in a single file BlogRepo
.
Summary
There are a few more ways to further improve this and make it better unit testable example, but hopefully it helps open up the brain waves to explore more possibilities.