Entity Framework 4 and SQLCE 4 CTPs Odds and Ends
There are already plenty of good walk through for using Code First with EF 4 CTP so this a mop of of some odds and ends I found useful. I’l update this post as further releases are made / I stumble across discover new features.
Adding the NuPack package
EF4 (currently at CTP2) is available as a NuPack package, soon to be NuGet. EFCTP4 can be added as a package by itself or the SQLCE.EntityFramework package can be added to a project and this will include EF4CTP as a dependency. This is my preferred root as I find it easier to develop with SQLCE then swap databases after most of the initial development is complete.
Presuming the solution has a separate project for a data layer, then that is the project the NuPack should be added to. The system.data element should then be copied from the web.config of the data layer (where the Nupack added it) to the web.config of the web front end.
Viewing the SQLCE 4 Database
The SQLCE tooling for VS 2010 and SSMS is yet to be released. WebMatrix alows some examination of SQL CE 4 database files, alternatively basic info can be viewed in VS2010 using SQL Server Compact Toolbox which is a VS addin that can be downloaded from the extension gallery.
Reseeding the database for each run
When developing it is useful to have the database in a known condition each time it is run. When the SQLCE Entity Framework package installed it added a AppStart_SQLCEEntityFramework class. We can use the start method of this class to set an initializer for the database:
Database.SetInitializer(new RavenInitializer());
We can then specify an initializer to recreate the database every time the app is started and prepopulate it:
public class RavenInitializer : AlwaysRecreateDatabase<RavenContext> {#region Instance Methodsprotected override void Seed(RavenContext context) {var tenants = new List<Tenant>{new Tenant{Id = 1,Name = "Tenant 1",PaidupUntil = DateTime.Now.AddMonths(1),SubscriptionLevel = 1},new Tenant{Id = 2,Name = "Tenant 2",PaidupUntil = DateTime.Now.AddMonths(-1),SubscriptionLevel = 2}};tenants.ForEach(t => context.Tenants.Add(t));}#endregion}
Conventions
Primary Key
If a class has a field called either Id or <class name>Id then that field will be used as a primary key.
Named Connection String
If a connection string exists in Web.Config with the same name as the context, EF4 will use it in preference to the standard db factory (see below for an example).
Coming Soon (as of CTP2)
The following are features that are not in CTP2 but are documented in various blogs.
Type Discovery
Currently, if EntityA has a property of type EntityB, EntityB will not persist to the database unless it has a DbSet exposed by the context or is registered as a complex type with the ModelBuilder. In a future release EntityB will be persisted automatically.
Bug Fix for ‘The database File already Exists’
There is currently an issue with EF4 CTP2, it attempts to recreate your SQLCE database every run resulting in an exception being thrown. The 2 workarounds for this are either to revert to CTP1 or specify a connection string in the web.config and remove the DataDirectory macro.
<connectionStrings><add name="RavenContext"connectionString="Data Source=Raven.sdf"providerName="System.Data.SqlServerCe.4.0" /></connectionStrings>
Not ideal but hopefully this will be fixed for the next release and we can go back to “Data Source=|DataDirectory|Raven.sdf”