The second part of my Entity Framework series is identical to the first, except this time I’m using Code First.  I’m not going to go into as much detail, but will show the differences.  As usual the code is hosted on github.

Add the DbContext & Generate POCO Classes

With Code First, there is no .edmx file, just a DbContext class and a set of POCO classes.  You will use the DbContext to load the POCO classes from the database.  Note that you should name your model Context vs. Model.   This is different than edmx, and confusing.

AddNewEntityContext

You’ll then select Code First from database:

EntityDataModelWizardDesignerCodeFirst

And choose your objects: (note that Stored Procedures and Functions are not available options)

EntityDataModelWizardCodeFirstChooseDatabaseObjects

After you finish the wizard, your project tree will look as follows: (you should probably put these into a sub folder e.g. \models)

BikeStoreCodeFirstClasses

Accessing the Context

From here the code is almost identical to the edmx version, with a few key differences.  First, instead of:

using (var db = new BikeStoreEntities())
 {
 //do database stuff
 }

You  call this:

using (var db = new BikeStoreContext())
 {
 //do database stuff
 }

Second, while the SQL executed is virtually identical, the first time the context is accessed, the following SQL executes:

IF db_id(N'BikeStore') IS NOT NULL SELECT 1 ELSE SELECT Count(*) FROM sys.databases WHERE [name]=N'BikeStore'

SELECT Count(*)
FROM INFORMATION_SCHEMA.TABLES AS t
WHERE t.TABLE_SCHEMA + '.' + t.TABLE_NAME IN ('product.Category','product.Model','product.Manufacturer','product.PartNumber','product.Status')
 OR t.TABLE_NAME = 'EdmMetadata'
 
exec sp_executesql N'SELECT 
 [GroupBy1].[A1] AS [C1]
 FROM ( SELECT 
 COUNT(1) AS [A1]
 FROM [dbo].[__MigrationHistory] AS [Extent1]
 WHERE [Extent1].[ContextKey] = @p__linq__0
 ) AS [GroupBy1]',N'@p__linq__0 nvarchar(4000)',@p__linq__0=N'CodeFirstBasicCRUD.BikeStoreContext'
SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT(1) AS [A1]
FROM [dbo].[__MigrationHistory] AS [Extent1]
) AS [GroupBy1]

SELECT TOP (1)
[Extent1].[Id] AS [Id],
[Extent1].[ModelHash] AS [ModelHash]
FROM [dbo].[EdmMetadata] AS [Extent1]
ORDER BY [Extent1].[Id] DESC

These SQL calls were not present in any of the edmx traces – these are support for Code First Migrations.  We can turn this off in the constructor of our context class:

public BikeStoreContext()
            : base("name=BikeStoreContext")
        {
            Database.SetInitializer<BikeStoreContext>(null); 
        }

Conclusion

At this point we have two approaches that achieve the same basic goal, but the basic question is why are there two approaches?  Apparently Microsoft feels this is a bad idea, so in EF 7 the emdx approach is being dropped.  Although it’s still early in my investigation, Code First feels cleaner, and I certainly have no love for large xml-based designer files.