I’m working with Entity Framework, trying to test code that hits it. All the code runs fine, but I’m having trouble with my testing. When I run this code when testing:
_entities = new Mock<MyEntities>();
Database.SetInitializer(new DropCreateDatabaseAlways<MyEntities>());
_entities.Object.Database.Initialize(true);
I get the “EntityType has no key defined” error. I was getting these before because some of the tables don’t follow the convention of naming their id columns “ID” or “[Table Name]ID.” After cleaning those up, I still get them for tables with a composite key. They’re defined correctly as far as SQL is concerned. In the EDMX designer, when I click on the columns, they say they’re keys. So how do I properly define them as keys? Where do I put the code?
I tried looking this up and ALL references are specifically to Code First implementations. I tried it anyway. They said to override the OnModelCreating method of the DbContext object and add this to it:
modelBuilder.Entity<Widgets>().HasKey(widget => new { widget.A, widget.B });
So I made a partial class and tried to override it. It was already overriden. So I went to the generated partial class. Here’s the implementation:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
So that’s not right. So what do I do now?
I want to generate a test database based off of the EDMX in my web project so I can create proper integration tests. Thanks in advance.
If you are using EDMX, you can’t use databsae initialization (or onmodelcreating). Those features are specific to Code First.
So there’s really no answer here because you can’t generate an test database from an EDMX.
There are some patterns you can follow for creating a test database on the fly. Pastingi from a blog post I wrote in 2009 (http://thedatafarm.com/blog/data-access/unit-testing-in-ef-v1-the-database-conundrum/)
Copy/Paste Database: Use a small SQL Server Express database as the
testing database. In the course of the particular test, copy/paste
the db file to a specific location and then open a connection to it.
At the end of the test, blow away the file.
Transactions: In each of the db access tests, wrap the code within a
System.Transaction.TransactionScope. At the end of the test, don’t
complete the transaction and the db will roll back.
DB Script:
Another client was using a small database that he would generate on
the fly at the start of each test and then remove the db at the end.
So given that, the place to define your key is (as I suggested on twitter) in your model. In the designer, right click on each entity property that belongs in the key and make sure “entity key” is clicked on the context menu. EF will then use the combination of those properties as it’s composite entity key.
Hope it helps.