Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In-Memory DB for Entity Framework 4

Does anyone know of a good in-memory DB that works well with .NET 4/EF 4? Specifically, I'm thinking of unit testing, such that each setup can easily create the DB, and populate it with default values, and each teardown can destroy it - in a quick fashion.

I've heard that SQLite doesn't support .NET 4 yet, and others have had trouble using it as a substitute for SQLServer (which is what the appliction will run on in release mode).

In the past, I used DevExpress XPO ORM and it had a built-in in-memory database that worked quite well for unit testing.

like image 739
Steven Evers Avatar asked Nov 16 '10 21:11

Steven Evers


3 Answers

You'll have a problem unit testing with CE4 if your model has database-generated keys (usually specified in EF4 using the [DatabaseGenerated(DatabaseGeneratedOption.Identity)] annotation), as CE4 doesn't support this.

But I found an easy workaround without needing to modify my production code (which runs on SQL 2008). I created a proxy sub-class of my DbContext, and in it overrode OnModelCreating to remove the annotation, and overrode SaveChanges to set the ID manually:

public class TestContext : MyDbContext
{
  protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
  {
    modelBuilder.Entity<MyEntity>().Property(e => e.Id)
      .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

    base.OnModelCreating(modelBuilder);
  }

  public override int SaveChanges()
  {
    foreach (var entry in ChangeTracker.Entries<MyEntity>().Where(e => e.State == EntityState.Added))
    {
      entry.Entity.Id = Guid.NewGuid();
    }
    return base.SaveChanges();
  }
}

With these minor tweaks, I can now unit test the same repository code in CE4 that runs under SQL 2008 in production.

And if you are using integer IDs rather than GUIDs, there's a nice extension method here that can be plugged right into the above solution: http://enigmadomain.wordpress.com/2010/01/06/sql-compact-identity-columns-and-entity-framework/

like image 181
Jeremy Bull Avatar answered Sep 18 '22 10:09

Jeremy Bull


SQL CE will do this for you. It's an embedded database that runs in process. It works with EF4 (including Code First). The easiest way to get it is to directly install the NuGet package for it. There are two NuGet packages - one that just has SQL CE and the other that has the SQL CE that works with the EF Code First CTP4.

like image 32
Steve Michelotti Avatar answered Sep 20 '22 10:09

Steve Michelotti


If it's not a problem for you to switch to EF CTP4 then it's like that:

EF4 CTP4 SQL CE 4 CTP

It will generate db in-memory for you as you write unit tests (code-first).

like image 40
mihcall Avatar answered Sep 18 '22 10:09

mihcall