This article will discuss how generic entity store operations towards a data context can be used
with EF Code First. This is tested with EF 6.
First, define an interface with the often used generic entity store operations:
using System;
using System.Data.Entity;
namespace TestEFCodeFirst1
{
public interface IRepo : IDisposable
{
T Insert<T>(T item, bool saveNow) where T : class;
T Update<T>(T item, bool saveNow) where T : class;
T Delete<T>(T item, bool saveNow) where T : class;
int Save();
}
}
Then implement this interface:
using System.Data.Entity;
namespace TestEFCodeFirst1
{
public class Repo<TContext> : IRepo
where TContext : DbContext, new()
{
public Repo()
{
Context = new TContext();
}
protected TContext Context { get; private set; }
#region IRepo Members
public T Insert<T>(T item, bool saveNow) where T : class
{
Context.Entry(item).State = EntityState.Added;
if (saveNow)
Context.SaveChanges();
return item;
}
public T Update<T>(T item, bool saveNow) where T : class
{
Context.Entry(item).State = EntityState.Modified;
if (saveNow)
Context.SaveChanges();
return item;
}
public T Delete<T>(T item, bool saveNow) where T : class
{
Context.Entry(item).State = EntityState.Deleted;
if (saveNow)
Context.SaveChanges();
return item;
}
public void Dispose()
{
Context.Dispose();
}
#endregion
#region IRepo Members
public int Save()
{
return Context.SaveChanges();
}
#endregion
}
}
Next, create a simple DbContext to test out:
public class DemoDbContext : DbContext
{
public DemoDbContext() : base("EFCodeFirstDemoDb1")
{
}
public DbSet<Student> Students { get; private set; }
}
An example of using this db context in a derived repo class is shown next:
public class DemoRepo : Repo<DemoDbContext>
{
}
The next code shows how to use this extension method:
using System;
using System.Data.Entity;
namespace TestEFCodeFirst1
{
class Program
{
static void Main(string[] args)
{
Database.SetInitializer(new Init());
using (var repo = new DemoRepo())
{
repo.Insert(new Student { Name = "Hardy", DateAdded = DateTime.Now,
LastMod = DateTime.Now}, true);
repo.Insert(new Student
{
Name = "Joey",
DateAdded = DateTime.Now,
LastMod = DateTime.Now
}, true);
}
}
}
}
To automatically patch your database do this:
In package-manager console type:
Enable-Migrations
In the configuration class, set
AutomaticMigrationsEnabled to true.
namespace TestEFCodeFirst1.Migrations
{
using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
internal sealed class Configuration : DbMigrationsConfiguration<TestEFCodeFirst1.DemoDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
protected override void Seed(TestEFCodeFirst1.DemoDbContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//
// context.People.AddOrUpdate(
// p => p.FullName,
// new Person { FullName = "Andrew Peters" },
// new Person { FullName = "Brice Lambson" },
// new Person { FullName = "Rowan Miller" }
// );
//
}
}
}
Add an Init class:
using TestEFCodeFirst1.Migrations;
namespace TestEFCodeFirst1
{
internal class Init : System.Data.Entity.MigrateDatabaseToLatestVersion
{
}
}
This explains what is done in the line further up:
Database.SetInitializer(new Init());