Code-First Development with Entity Framework 4

.NET 4 ships with a much improved version of Entity Framework (EF) – a data access library that lives in the System.Data.Entity namespace.

When Entity Framework was first introduced with .NET 3.5 SP1, developers provided a lot of feedback on things they thought were incomplete with that first release.  The SQL team did a good job of listening to this feedback, and really focused the EF that ships with .NET 4 on addressing it. 

Some of the big improvements in EF4 include:

  • POCO Support: You can now define entities without requiring base classes or data persistence attributes.
  • Lazy Loading Support: You can now load sub-objects of a model on demand instead of loading them up front.
  • N-Tier Support and Self-Tracking Entities: Handle scenarios where entities flow across tiers or stateless web calls.
  • Better SQL Generation and SPROC support: EF4 executes better SQL, and includes better integration with SPROCs
  • Automatic Pluralization Support: EF4 includes automatic pluralization support of tables (e.g. Categories->Category).
  • Improved Testability: EF4’s object context can now be more easily faked using interfaces.
  • Improved LINQ Operator Support: EF4 now offers full support for LINQ operators.

Visual Studio 2010 also includes much richer EF designer and tooling support. The EF designer in VS 2010 supports both a “database first” development style – where you construct your model layer on a design surface from an existing database.  It also supports a “model first” development style – where you first define your model layer using the design surface, and can then use it to generate database schema from it.

Code-First Development with EF

In addition to supporting a designer-based development workflow, EF4 also enables a more code-centric option which we call “code first development”.  Code-First Development enables a pretty sweet development workflow.  It enables you to:

  • Develop without ever having to open a designer or define an XML mapping file
  • Define your model objects by simply writing “plain old classes” with no base classes required
  • Use a “convention over configuration” approach that enables database persistence without explicitly configuring anything
  • Optionally override the convention-based persistence and use a fluent code API to fully customize the persistence mapping

EF’s “code first development” support is currently enabled with a separate download that runs on top of the core EF built-into .NET 4.  CTP4 of this “code-first” library shipped this week and can be downloaded here

It works with VS 2010, and you can use it with any .NET 4 project (including both ASP.NET Web Forms and ASP.NET MVC).

Step by Step Tutorial: Building NerdDinner using a Code-First Approach

Last year I wrote an ASP.NET MVC 1.0 tutorial that was published both online and in a book.  The tutorial walked through creating a simple application, called “NerdDinner”, which provides an easy way for people to organize, host and RSVP for dinners online.  You can read my original ASP.NET V1 NerdDinner tutorial here.  An updated version of the tutorial is also included in the new Professional ASP.NET MVC 2 book.

The NerdDinner tutorial used a “database first approach” where the database schema was defined first, and then we used a Visual Studio designer to create our LINQ to SQL / LINQ to Entities model objects that mapped to it.  

Below I’m going to demonstrate how we could instead use a “code first approach” using EF4 to build the NerdDinner model layer and database schema, and construct a CRUD application using ASP.NET MVC.

image

We will walkthrough building this application step-by-step.  A download link to a completed version of the sample is available at the end of this blog post.

Step 1: Create a New Empty ASP.NET MVC 2 Application

We’ll start by creating a new ASP.NET MVC 2 Project within Visual Studio 2010.  Choose File->New Project and use the “ASP.NET MVC 2 Empty Web Application” project template to do this.

This will create an empty ASP.NET MVC 2 project that does not have any controllers, models or views within it:

image

We’ll next work to define our NerdDinner “model” – which refers to the objects that represent the data of our application, as well as the corresponding domain logic that integrates validation and business rules with it.  The model is the "heart" of an MVC-based application, and fundamentally drives the behavior of it.  We’ll create this model layer using the new EF4 “Code First” capabilities.

Step 2: Create our Model

Let’s assume we do not already have a database defined, and that we are building our new NerdDinner application completely from scratch.

We do not need to start with a database

When using a code-first development workflow, we do not need to begin our application by creating a database or specifying schema.  Instead we can begin by writing standard .NET classes that define the domain model objects that are most appropriate for our application – without having to worry about intermixing data persistence logic within them.

Creating Model Classes

NerdDinner is a small application, and our data storage needs with it are pretty simple.  We want to be able to define and store “Dinners” that refer to specific events that people can attend.  We also want to be able to define and store “RSVP” acceptances, which are used to track a person’s interest in attending a particular Dinner.

Let’s create two classes (Dinner and RSVP) to represent these concepts.  We’ll do this by adding two new classes to our ASP.NET MVC project - “Dinner” and “RSVP”:

image

The above “Dinner” and “RSVP” model classes are “plain old CLR objects” (aka POCO).  They do not need to derive from any base classes or implement any interfaces, and the properties they expose are standard .NET data-types.  No data persistence attributes or data code has been added to them. 

The ability to define model classes without having to tie them to a particular database, database API, or database schema implementation is really powerful – and provides us with much more data access flexibility.  It allows us to focus on our application/business needs without having to worry about persistence implementation.  It also gives us the flexibility to change our database schema or storage implementation in the future – without having to re-write our model objects, or the code that interacts with them.

Creating a Context Class to Handle Database Persistence

Now that we’ve defined our two POCO model classes, let’s create a class that we can use to handle the retrieval/persistence of Dinner and RSVP instances from a database. 

We’ll name this class “NerdDinners”. It derives from the DbContext base class, and publishes two public properties – one that exposes our Dinner objects, and one that exposes our RSVP objects:

image

The DbContext and DbSet classes used above are provided as part of the EF4 Code-First library.  You’ll need to add a reference to the System.Data.Entity.CTP assembly that is installed into the \Program Files\Microsoft ADO.NET Entity Framework Feature CTP4\Binaries directory to reference these classes.  You’ll also want to add a “using System.Data.Entity” namespace statement at the top of your “NerdDinners” class file.

That is all the code we need to write

The above three classes contain all of the code necessary to implement a basic model and data persistence layer for our NerdDinner application.  We do not need to configure any additional database schema mapping information, nor run any tools, nor edit any XML files, nor use any designers in order to start using our classes to retrieve, update, and save data into a database.

Convention Based Persistence Mapping

We do not need to write any additional code, nor create any XML files, nor use any tools in order to map our model classes to and from a database.  How, you might ask, is that possible?

By default, EF code-first supports a “convention over configuration” approach that enables you to rely on common mapping conventions instead of having to explicitly configure things.  You can override these conventions if you want to provide custom database mapping rules.  But if you instead just use the default conventions you’ll find that the amount of code you have to write is really small, and the common 90% of scenarios “just work” the way you’d expect them to without any extra code or configuration.

In our example above, our NerdDinners context class will by default map its “Dinners” and “RSVPs” properties to “Dinners” and “RSVPs” tables within a database.  Each row within the Dinners table will map to an instance of our “Dinner” class.  Likewise, each row within the RSVPs table will map to an instance of our “RSVP” class.  Properties within the “Dinner” and “RSVP” classes in turn map to columns within the respective “Dinners” and “RSVPs” database tables.

Other default conventions supported by EF include the ability to automatically identify primary-key and foreign keys based on common naming patterns (for example: an ID or DinnerID property on the Dinner class will be inferred as the primary key).  EF also includes smart conventions for wiring-up association relationships between models.  The EF team has a blog post that talks more about how the default set of conventions work here.

Code Examples of How to Use Our Model

The three classes we created earlier contain all of the code necessary to implement our model and data persistence for NerdDinner.  Let’s now look at a few code examples of how we can use these classes to perform common data scenarios:

Query Using LINQ Expressions

We can write LINQ query expressions to retrieve data from a database using the following code.  Below we are using a LINQ expression to retrieve all dinners that occur in the future:

image

We can also take advantage of relationships between Dinners and RSVPs when writing our LINQ expressions.  Notice below how our “where” statement filters by dinners whose RSVP count is greater than 0:

image

Note that the “where” filter in the above query (where we are retrieving only those Dinners who have at least one RSVP) executes in the database server – making the query and the amount of data we retrieve very efficient.

Retrieving a Single Instance

We can use LINQ’s Single() method with a lambda query to retrieve a single instance of a Dinner using code like below:

image

Alternatively, we can also take advantage of a Find() method that EF “code-first” exposes that allows you to easily retrieve an instance based on its ID:

image

Adding a new Dinner

The code below demonstrates how to create and add a new Dinner to the database.  All we need to do is to “new” a Dinner object, set properties on it, and then add it to the Dinners property of our NerdDinners context object.  The NerdDinner context class supports a “unit of work” pattern that enables you to add multiple models to the context, and then call “SaveChanges()” on it to persist all of the changes to a database as a single atomic transaction.

image

Updating a Dinner

The code below demonstrates how to retrieve a Dinner, update one of its properties, and then save the changes back to the database:

image

Step 3: Create a ASP.NET MVC Controller that uses our Model

Let’s now look at a more complete scenario involving our model, where we use a controller class to implement the functionality necessary to publish a list of upcoming dinners, and enable users to add new ones:

image

We’ll implement this functionality by right-clicking on the “Controllers” folder and choose the “Add->Controller” menu command.  We’ll name our new controller “HomeController”.

We’ll then add three “action methods” within it that work with the NerdDinners model we created earlier using EF “Code-First”:

image

The “Index” action method above retrieves and renders a list of upcoming dinners. 

The “Create” action methods allow users to add new dinners.  The first “Create” method above handles the “HTTP GET” scenario when a user visits the /Home/Create URL, and send back a “New Dinner” form to fill out.  The second “Create” method handles the “HTTP POST” scenario associated with the form – and handles saving the dinner in the database.  If there are any validation issues it redisplays the form back to the user with appropriate error messages.

Adding Views for our Controllers

Our next step will be to add two “View templates” to our project – one for “Index” and one for “Create”. 

We’ll add the “Index” view to our project by moving our cursor within the Index action method of our controller, and then right-click and choose the “Add View” menu command.  This will bring up the “Add View” dialog.  We’ll specify that we want to create a strongly-typed view, and that we are passing in a IEnumerable list of “Dinner” model objects to it:

image

When we click “Add”, Visual Studio will create a /Views/Home/Index.aspx file.  Let’s then add the following code to it – which generates a <ul> list of Dinners, and renders a hyperlink that links to our create action:

image

We’ll then add the “Create” view to our project by moving our cursor within the Create action method of our controller, and then right-click and choose the “Add View” menu command.  Within the “Add View” dialog we’ll specify that we want to create a strongly-typed view, and that we are passing it a Dinner object.  We’ll also indicate that we want to “scaffold” using a “Create” template:

image

When we click “Add”, Visual Studio will create a /Views/Home/Create.aspx file with some scaffold-generated content within it that outputs an HTML <form> for a “Dinner” object.  We’ll tweak it slightly and remove the input element for the DinnerID property.  Our final view template content will look like this:

image

We have now implemented all of the code we need to write within our Controller and Views to implement the Dinner listing and Dinner creation functionality within our web application.

Step 4: The Database

We’ve written our code.  Now let’s run the application. 

But what about the database?

We don’t have a database yet – and haven’t needed one so far because our “code first” development workflow hasn’t required us to have one to define and use our model classes. 

But we will need a database when we actually run our application and want to store our Dinner and RSVP objects.  We can create the database one of two ways:

  1. Manually create and define the schema ourselves using a database tool (e.g. SQL Management Studio or Visual Studio)
  2. Automatically create and generate the schema directly from our model classes using the EF Code-First library

This second option is pretty cool and is what we are going to use for our NerdDinner application.

Configuring our Database Connection String

To begin with, we’ll setup a connection-string to point to where we want our database to live.  We’ll do this by adding a “NerdDinners” connection-string entry to our application’s web.config file like so: 

image 

By default, when you create a DbContext class with EF code-first, it will look for a connection-string that matches the name of the context-class.  Since we named our context class “NerdDinners”, it will by default look for and use the above “NerdDinners” database connection-string when it is instantiated within our ASP.NET application.

Taking advantage of SQL CE 4

You can use many different databases with EF code-first – including SQL Server, SQL Express and MySQL.

Two weeks ago I blogged about the work we are also doing to enable the embedded SQL CE 4 database engine to work within ASP.NET.  SQL CE 4 is a lightweight file-based database that is free, simple to setup, and can be embedded within your ASP.NET applications.  It supports low-cost hosting environments, and enables databases to be easily migrated to SQL Server.

SQL CE can be a useful option to use when you are in the early stages of defining (and redefining) your model layer – and want to be able to quickly create and recreate your database as you do so.  We’ll use SQL CE 4 to begin with as we develop our NerdDinner application.  We can later optionally change the connection-string to use SQL Express or SQL Server for production deployment – without having to modify a single line of code within our application.

The connection-string I specified above points to a NerdDinners.sdf database file, and specifies the SQL CE 4 database provider.  In order for this to work you need to install SQL CE 4 – either via the Standalone SQL CE Installer or by installing WebMatrix (which includes it built-in).  SQL CE 4 is a small download that only takes a few seconds to install.

Important: In the connection-string above I’m indicating that we want to create the NerdDinners.sdf file within the |DataDirectory| folder – which in an ASP.NET application is the \App_Data\ folder immediately underneath the application directory.  By default the “Empty ASP.NET MVC Web Application” project template does not create this directory.  You will need to explicitly create this directory within your project (right click on the project and choose the “Add->ASP.NET Folder->Add_Data” menu item).

Automatic Database Schema Creation

EF code-first supports the ability to automatically generate database schema and create databases from model classes – enabling you to avoid having to manually perform these steps.

This happens by default if your connection-string points to either a SQL CE or SQL Express database file that does not already exist on disk.  You do not need to take any manual steps for this to happen.

To see this in action, we can press F5 to run our NerdDinner application.  This will launch a browser at the root “/” URL of our application.  You should see a screen like below rendered back:

image

The “/” URL to our application invoked the HomeController.Index() action method – which instantiated and queried our NerdDinners context object to retrieve all upcoming Dinners from our database.  Because the NerdDinners.sdf database file we pointed our connection-string to didn’t already exist, the EF code-first library automatically generated it for us.  It used our NerdDinners context object to automatically infer the database schema for the database it generated. 

To see the SQL CE database file that was generated, click the “Show all Files” icon within the Visual Studio solution explorer, and then press the “Refresh” button and expand the App_Data folder:

image 

We will be shipping an update to VS 2010 in the future that enables you to open up and edit SQL CE 4 databases within the “Server Explorer” tab (just like you do with SQL databases today).  This will enable you to easily see (and optionally tweak) the schema and contents of the database.  Until then you can optionally use the database tools within WebMatrix to examine the SQL CE 4 database file’s contents. 

We did not specify any custom persistence mapping rules with our NerdDinners context – so the database that was generated followed the default EF code-first naming conventions to map the schema.  If we had specified any custom mapping rules, though, the EF code-first library would have honored those and generated a database that matched them. 

Just to refresh our memory – here are the two POCO model classes and the NerdDinners context class that we defined earlier:

image

Below are the tables that were added when we ran our application and the database was automatically created based on the above model:

image 

The definition of the “Dinners” table looks like below.  The column names and data-types map to the properties of the Dinner class we defined.  The DinnerID column has also been configured to be both a primary key and an identity column:

image

The definition of the “RSVPs” table looks like below.  The column names and data-types map to the properties of the RSVP class we defined.  The RsvpID column has also been configured to be both a primary key and an identity column:

image

A one to many primary key/foreign key relationship was also established between the Dinners and RSVPs tables.  The EF code-first library inferred that this should be established because our Dinner class has an ICollection<RSVP> property named RSVPs, and the RSVP class has a Dinner property.  

Populating the Database with some Dinners

Let’s now create and add some Dinners to our database.  We’ll do this by clicking the “Create New Dinner” link on our home-page to navigate to our “Create” form:

image

When we click the “Create” button, our new Dinner will be saved in the database.  We can repeat this multiple times to register several different Dinners.  Each new Dinner we create will be persisted within our database and show up in our Home listing of upcoming dinners:

image 

Step 5: Changing our Model

We are going to continually evolve and refactor our model as our application grows.  The EF code-only library includes some nice development features that make it easier to coordinate this evolution with a development database.

Adding a new Property to the Dinner Model

Let’s walkthrough making a simple change to our Dinner class.  Specifically, we’ll add an additional property to our Dinner class called “Country”:

image

Now that we’ve made this change, let’s press F5 in Visual Studio to build and re-run the application.  When we do this we’ll see the below error message:

image

This error message occurs because we’ve changed the structure of our Dinner class, and our model object is now no longer the same shape as the “Dinners” table we automatically created within our database. 

When EF automatically creates a database for you, it by default adds an “EdmMetadata” table to the database that tracks the shape of the model objects that were used to automatically create the database schema for you: 

image

The error message above occurs when EF detects that you’ve made a change to a model object and it is now out of sync with the database it automatically created for you. 

Re-synchronizing our Model Classes with the Database

There are a couple of ways we can “re-sync” our model objects and our database:

  • We can manually update our database schema to match our models
  • We can manually delete our database file, re-run the application, and have EF automatically re-create the database
  • We can enable a feature of EF code-first that automatically updates our database for us whenever we change our models

Let’s look at how we can use this last automatic option with our NerdDinner application.

The RecreateDatabaseIfModelChanges Feature

CTP 4 of the EF Code First library includes a useful development-time feature that enables you to automatically re-create your database anytime you make modifications to your model classes.  When you enable it, EF identifies when any of the model classes that were used to automatically create a database are modified, and when that happens can re-create your database to match the new model class shape – without you having to take any manual steps to do so.

This capability is especially useful when you are first developing an application, since it gives you the freedom and flexibility to quickly refactor and restructure your model code however you want - without having to do any manual work to keep your database schema in sync along the way.  It works especially well with SQL CE – since it is a file-based database that can be dropped and recreated on the fly in under a second.  This can enable an incredibly fluid development workflow.

The easiest way to enable this capability is to add a Database.SetInitializer() call to the Application_Start() event handler within our Global.asax class:

image

This tells EF to re-create our NerdDinners.sdf database to match our NerdDinners model anytime our model classes change shape.  Now when we re-run our application we will no longer get that error message telling us that our model classes and database are out of sync.  EF will instead automatically re-create a database for us that matches our new model class shape, and our application will run fine:

image

Seeding Initial Data in Automatically Created Databases

One of the things you might have noticed in the above screen-shot is that we lost our dinner data when we recreated the database.  This is because the automatic “RecreateDatabaseIfModelChanges” behavior isn’t intended for production scenarios where you want to “migrate” existing data from one schema to another.  Instead it is designed for development scenarios where you want the database to be quickly and automatically updated for you – without you having to take any manual steps or specify migration rules to do so. 

Note: We are separately working to provide better data migration support for scenarios where you are working with production data and want to version the schema.  We think of that as a different scenario than this early development-time feature that I’m describing here.  The data migration capability isn’t enabled yet with this week’s CTP.

EF supports the ability for us to optionally “seed” our generated database with default/test data anytime the database is created/recreated.  I find this feature really useful since it enables me to refactor a model, and then quickly run the application to try out a scenario – without having to enter in a bunch of test data manually to do so.

We can “seed” our NerdDinners database with default data by writing a “NerdDinnersIntializer” class like below.  I’m using it to create two “sample dinners” and adding them to our database like so:

image

We can then update the Database.Initializer() call we added to our Global.asax to use this “NerdDinnersInitializer” class at startup:

image

And now anytime we make a change to one of our NerdDinner model classes, the database will be automatically dropped and recreated to match our models, and we’ll have two dinners already seeded in the database for testing purposes:

image

Easy Refactoring

The above features make it really easy to evolve and refactor your code at development time – without having to use tools or run scripts to manually keep your database in sync with your code changes.

Because our model classes, LINQ expressions, and “seed” test data are all strongly typed, we can also take advantage of refactoring tool support inside Visual Studio to quickly and automatically apply changes across our code base in a quick and easy way.

Step 6: Adding Validation Rules

We’ve built a nice, simple data-entry application.

One problem with it, though, is that we don’t currently have any type of input validation in place to ensure that fields are filled out correctly within our Create Dinner form.  Let’s fix that.

Adding Validation using DataAnnotations

Validation rules in an ASP.NET MVC based application are usually best expressed within a model.  This enables them to be maintained in a single place, and enforced across any number of controllers and views that might interact with them.  ASP.NET MVC enables you to implement validation rules using a variety of different mechanisms, and is flexible enough to support just about any validation scheme you want to use. 

ASP.NET MVC 2 includes built-in support for using .NET’s System.ComponentModel.DataAnnotations library of validation rules – which enable you to declaratively apply validation rules to model classes using validation attributes.  You can learn more about this capability in a previous blog post I wrote.  We’ll take advantage of this approach to enable input validation for our NerdDinner application.

Let’s go back to the Dinner class we defined earlier and add some validation attributes to its properties (note: we need to add a “using System.ComponentModel.DataAnnotations” namespace as well):

image

The [Required] validation attribute indicates that a particular property must be specified.  The [StringLength] validation attribute allows us to indicate a maximum length for a particular string property.  The [RegularExpression] validation attribute allows us to indicate that a particular string property must match a specified regular expression in order to be valid – in this case an email address.

Each of the validation attributes supports an “ErrorMessage” property – which allows us to specify an error message that should be displayed if the validation fails.  This can either be hard-coded as a string (like above) or pulled from a resource – enabling it to be easily localized.

Referencing some CSS and JavaScript files

The last step will be to go back to our Create.aspx view template and add a <link> reference to a Site.css file in our project, as well as two <script> elements that reference two JavaScript files in our project.  We’ll also add one line of code to call Html.EnableClientValidation() before our <form> element is rendered:

image

These changes will ensure that any validation error messages that are displayed in the page are styled (to make them more visible), and that the validation rules we apply on our model will be applied both on the client and on the server.

Running the Application

Let’s re-run the application and try to create a new Dinner.  Let’s begin by pushing the “Create” button with no values filled out.  We’ll find that we now see the validation error messages we applied to our model showing up in the browser:

image

Because we enabled client-side validation with ASP.NET MVC (that was the one line of code we wrote above), our error messages will update and change in real-time:

image

Notice above how our validation error message changed once our “Title” became longer than 20 characters.  This is because we have a [StringLength] property on our Dinner.Title property that indicates a maximum allowed size of 20 characters.  As we started entering a value within the “HostedBy” textbox, our error message likewise changed from the “[Requred]” error message (which asks you to enter your email address) to the “[RegularExpression]” error message (which is telling us we don’t have a valid email address).

These validation rules work both within the browser (via JavaScript) and on the server (enabling us to protect ourselves even if someone tries to bypass the JavaScript validation) – without us having to make any changes to our controller class.  The ability to specify these rules once within our model, and have them apply everywhere, is extremely powerful – and will enable us to continue to evolve our application in a very clean way. 

You can learn more about these ASP.NET MVC 2 Model Validation features and how they work here.

Download

Click here to download and run the above NerdDinnerReloaded sample we’ve built in this blog post.  It requires VS 2010 (or the free Visual Web Developer 2010 Express). 

Important: You must download and install SQL CE 4 on your machine for the above sample to work.  You can download the EF Code-First library here.  Neither of these downloads will impact your machine.

Summary

This week’s CTP4 release of the “EF Code-First” functionality provides a pretty nice code-centric way to work with data.  It brings with it a lot of productivity, as well as a lot of power.  In today’s tutorial I focused mostly on some of the new productivity enhancements provided with the CTP4 release.  There are many more scenarios we could drill into including its Fluent API for enabling custom persistence mapping rules, its improved testability support, and other more advanced capabilities.

You can download this week’s CTP4 release of EF Code-First here.  To learn even more about “EF Code-First” check out these blog posts by the ADO.NET team:

Hope this helps,

Scott

P.S. In addition to blogging, I am also now using Twitter for quick updates and to share links. Follow me at: twitter.com/scottgu

148 Comments

  • Seriously kicks ass!

  • Great post Scott! I finally have a reference to start my EF journey, hope you find more time to help developers adopt more goodies from Microsoft through excellent blog posts.

    Cheers,
    Indyfromoz

  • This release is what we're actually waiting for. Great post. And like Hanselman said: this is truly "EF Magic Unicorn"!

  • Thanks for the post Scott, this is what I personally always wanted (and hoped) would be in EF. It's a very compelling reason to hasten our move to .NET 4.

    What is the performance expected to be like compared to the traditional EF approach?

  • Nice post, Scott - looking forward to trying this out on an upcoming project of mine. Two quick questions though:

    1. When database tables are generated from the POCO:s, are string properties translated into nvarchar(max)? Or is the length of the nvarchar dependent on the StringLength attribute (if present)?
    2. Are enum properties supported on the POCO:s?

    Best regards,

    Anders

  • Is there any way to work with geometry and geography types with this or is that still not doable yet?

    Beyond that I plan to abuse this quite a bit, especially the default data. It will easily let me use the same data in unit tests when dealing with a repository and when building that repository.

  • Awesome! I decided to drop my ORM for EF at just the right time!

    What about change tracking? With this code is EF still able to update a record's changes only? Also, is DbContext thread-safe?

  • A great post which compliments Mr Hanselman's "Magic Unicorn" post nicely.

    I see some great benefits of using this approach to rapid application development, and potentially also this will help in initialising QA environments after having developed a project potentially using SQL CE locally.

    Very interesting stuff and looking forward to seeing further development of this feature.

  • Thanks for the great improvements on EF. Every release I get closer to actually be able to use it.

    My question from day 1 has been about database versioning. It seems EF has never really worried about database schema changes over time, and has always had a "just recreate the database when the schema changes and stop bothering me" attitude.

    I write systems that store really valuable data (who doesn't?) and if I use anything that has even the remotest possibility of erasing data eventually it'll get me fired. I absolutely, positively need to have certainty that deployed installations will not lose data as part of a version upgrade that updates the schema.

    Having said that, what I do now is use a versioned system where there is a table with one field and one record that holds the schema version number, and in my app's code I check the version upon startup and upgrade as needed (or deny access if the database version is higher than what the executable can handle). The rest of my DB access methodology probably looks like the handwritten version of what EF does automatically (which is a LOT of code!).

    Under what scenario would the new EF allow me to have the certainty of schema integrity that I have now? I do not want someone, for example, to run an older app version and downgrade the schema, or for a schema version change to not work out the same on two machines. (what happens if someone updates two versions instead of one, will EF make sure the schema [and the data] changes correctly in this case too?)

    Would the new EF support anything close to what I describe now? All the time I have read about how great EF is for development, but I need an EF that's great for deployment.

  • Amazing work. I'm actually working on the data access layer for my current project and this is a very welcome addition to EF4 that will make my life a lot easier.

    Thanks, and big up to you guys !

  • That is the coolest quickstart functionality for projects ever.
    You can start working on the meaty problems immediately without having to plod through the data access shenanigans first.

    Brilliant!

  • This is very cool. To deal with model changes it might be a good idea to look into Rails-style migrations in a future version of EF.

  • Very nice - after working through the POCO EFv4 tutorials and getting edmx files last week , this approach is much more favorable to me

    Now I can use the templates to generate locks in legacy database models without needing to mess with the XML mapping files

  • Hey,

    I like the idea of even faster prototyping and waiting eagerly for the data-migration capability ;-D

  • Hi Scott,

    Great article! Quick question: can EF utilise the power of TVPs (table value parameters) when calling stored procedures?

  • Holy macro. Unicorn indeed. Exactly what I'm eating for.
    thanks ef team and thanks Scott for another great post.

    How about a post on sp support. Or can you point us to an article
    that tells how to get data using sps?

    Thanks
    zm

  • Amazing! I can't wait to get my hands dirty with this! Great stuff!

  • is it the beginning of "goodbye nhibernate"?

  • Thanks Scott.

    In an upcoming blog post could you provide an example of EF Code-First that turns out to be a many-to-many relational scenario?

    You have exposed a few conventions over configurations for a one-to-many scenario; I guess that a MTM scenario must be as easy to implement as the OTM scenario as long as a few conventions are respected. In such a case I would figure out that both entities could expose a property of type IEnumerable.

    I love your detailed, step-by-step tutorials ;)

  • Scott,

    In the Dinner class you expose the RSVPs as a virtual ICollection.
    Can you expose the RSVPs as a virtual IEnumerable or ReadOnlyCollection with a private setter?

    This way we could use Add methods such as AddRsvp() instead of exposing the collection's Add method which defeats the purpose of the AddRsvp() method.

  • Great post Scott! Code first makes EF4 much more attractive to DDD developers and could now be considered as an alternative to NHibernate. All we need now is some good documentation of more advanced mapping scenarios.

  • Does the validation with attributes support multi-lingual?

  • That's a great post Scott!!!

  • This is what good developers need...

  • Can I ask what everyone thinks of DinnerID as the name of the primary key?

    I have always built my Pocos where the ID is just ID. So when coding it turns into

    var dinner = new Dinner();
    var output = FetchAllByDinnerId(dinner.Id);

    But I have noticed the trend in books and publications is to have dinner.DinnerID. Should we not all go on a diet and stop having this extra "Dinner" (sorry for the pun).

    Colin

    PS Entity Framework 4...looks awesome.

  • Is there any support for automatic schema changes to an existing database? If a new field is added to the Dinner class is there an automatic way to have EF create the new column instead of dropping and recreating the database?

  • Credit where credit is due, this is good stuff coming out of the EF team. EF Magic Unicorn - putting the M in ASP.NET MVC since 2010

  • @colin.wiseman - the article says "Other default conventions supported by EF include the ability to automatically identify primary-key and foreign keys based on common naming patterns (for example: an ID or DinnerID property on the Dinner class will be inferred as the primary key"
    Looks like you'll be all set then

  • This is great. I'd like to tweak this to use Razor, is there a place to download that other than through the WebMatrix download?

  • Scott, this is great. Code-first (or at least define-once) for the model layer is really what we all want. I've never found starting with the db as natural as starting with the OO code layer.

    Now, what I think will be an amazing stack for development and prototyping is:

    Razor Views + MVC Controllers + EF Code-First + SQL CE

    RecreateDatabaseIfModelChanges is a huge help. You mention it is a development-time feature. Is there an underlying feature of EF we can use to generate that schema change and deploy it on production databases separately as part of a more formal process?

  • It's good that Entity Framework is taking steps toward more simplified development, and not following the initial push of really hard core and abstract data access slash ORM framework. Also maybe this will be the long-awaited "M" in the MVC. It seems to align perfectly with the convention over configuration ideology of MVC. It will be good to know how EF plays with legacy C# data access code and more specific - is it possible to use Interfaces with the POCO classes and is it possible to detach an object pass it through application layers and attach it again.

  • Awesome stuff. Entity Framework is shaping up very nicely!

    Kudos

  • It would be nice if things would stop forcefully autogenerating other things. We just want to map to our database, not make it from scratch.


    Manually create and define the schema ourselves using a database tool (e.g. SQL Management Studio or Visual Studio)

    I'd much rather do this so that I fully understand the schema and structure done. But I've yet to see a CodeFirst example that explains how to connect to an existing database.

  • "By default, when you create a DbContext class with EF code-first, it will look for a connection-string that matches the name of the context-class."

    What if I don't want this default behavior? I see there is a proposed attribute for DataAnnotations called DataStoreName, but until this is implemented is there any way to tell your context that it should look for a db with a different name?

  • Oh yeah it looks very nice, MS is working on those things that previously existed in another platforms and they are important.

    The implementation looks great!

    Thank you for this excelent post Scott!

  • Does WCF Data Services work with this? Couldn't figure out what to put in my DataService tag.

  • Scott, last year at the PDC a prototype of ActiveRecord was shown running on top of the previous code-only CTP. Is ActiveRecord something still being worked on? MVC with ActiveRecord would be a major win.

  • Unless things have changed since the beta, there are a couple of gotchas. (Note: I'm not a DB expert, and this is just a single project.)
    I wrote a fairly data-intensive specalized logging analysis application.
    Some notes:
    - FWIR, there was no simple way to delete objects from w/in the framework - specailized direct queries or SP's were needed to do this effectively.
    - Model-first and DB generation worked great for the most part. The issue is model changes that occur post-generation (such as adding or removing cols) - the tools are not able to perform a DDL delta on the DB, so if you change your model you need to change the DB manually. (I know this is a hard task in the general case, but the tools could do simple cases on assurance from the user to perform the operation.)
    - The model files and the UI had many bugs causing things to get out-of-sync and neededing reloading or manual fixing up of the XML model files - again, things may have improved here in the final bits.


  • Great stuff!
    Thanks Scott.

  • This is great news. Will try it out to see how it compares to LLBLGen and NHibernate.

  • by A

    "Does the validation with attributes support multi-lingual?"

    Simple use resource file.
    [Required(ErrorMessageResourceType=typeof(ValidationStrings),ErrorMessageResourceName="Required")]

  • The CTP license appears to prohibit Production deployment. This is a shame really. It would be nice to have a licence for the CTPs that allowed use perhaps in Intranet/Extranet/Departmental apps, even whilst knowing that API changes (and some bugs) would be present in the CTP.

  • The code-first approach looks exciting.

    Thia approach makes mapping from object to data table much easier. But what it's saying about deployment is never appealing to me. Dev and Prod are totally separate in most of business IT divisions. In addition, I can not count on the sql script auto generated by vs.net.

    However, the change on both database and .net code is pretty simple. First, change the database and then modify the EF4 code. That simple!

  • *Since we named our context class “NerdDinners”, it will by default look for and use the above “NerdDinners” database connection-string when it is instantiated within our ASP.NET application.*

    Is there a way around this default functionality (ie I want different names for my dbcontext and connectionstring) ? The closest thing that I can find is a *proposed* addition to DataAnnotations that's not available yet.

  • It's a dream come true specially for developers like me who used NHibenate and how painfull to keep the two sides in sync. Just great stuff, thanks for that. By the I am reading your article from my iPhone and it's 5 am.

  • Scott,

    Very nice stuff but to nitpick.. The logo on the download page of the CTP4 is still the the colorful Visual Studio 2008 one. That is a bit confusing because I think you can only use it in VS 2010.

  • Is there any support for automatic schema changes to an existing database?

  • Looks good so far. What I haven't seen in this tutorial is how to add custom attributes to the model that should not be in the database. Also, when a model has a list of entities attached to it (like an Order has a list of Products) can we use IList Products {get;set;} or does it have to be ICollection?

    Please do not underestimate the importance of a synchronization tool. The scenario you used here, with creating the database from scratch, is very limited. The vast majority of the time we need to compare the model with an existing (development) database and synchronize the two without losing data. If the automatic synchronization is too much work, then we at least need a way to compare the database with the model and have a list of deltas.

    Thanks.

  • Does this code first approach support more advanced mapping scenarios such as class inheritance mapping and component mapping, for instance if I want to map an Address value type on a Customer entity (as per domain driven design)? Sorry to constantly compare EF to NHibernate but Nhibernate does support these advance mapping constructs, though it's good to see EF catching up.

  • Scott - I hope that the EF4 team is talking to the DB Pro team about Code-First and how it may work with DB Pro. It would be good for MS to have a strategy before the Code First feature ships on how the DB Creation capability would be migrated over to a more sustainable model - I can see reasons to start out using Code First on a project and then at some future maturity point want to leverage the benefits of DB Pro (Data Dude) to manage the DB Schema objects. It sounds like there are plans to mature the EF way of updating databases (perhaps to enable something similar to Rails migration capabilities) - I will hope for a story that includes DB Pro as well because I see Code First being useful for a lot of apps even Enterprise ones initially that down the road will need more rigor - it would be disappointing for that scenario to not be considered. Thanks for all of the great new stuff - keep it coming!

  • Looks like 1 more release of EF and it will be a serious competitor to NH.

  • Please ignore my previous comment about the metadata I had missed the ModelBuilder.

    Regards,

    Santos

  • @James,

    >>>>>>> Thanks for the post Scott, this is what I personally always wanted (and hoped) would be in EF. It's a very compelling reason to hasten our move to .NET 4. What is the performance expected to be like compared to the traditional EF approach?

    The "code first" library uses the same underlying EF as the traditional approach - so the performance characteristics should be about the same. The "code first" library also includes aome smarts so that the meta-data that is retrieved for mapping to/from the database is cached - so that it only needs to be calculated once (which improves performance a lot).

    Hope this helps,

    Scott

  • @Anders,

    >>>>>>>>>>1. When database tables are generated from the POCO:s, are string properties translated into nvarchar(max)? Or is the length of the nvarchar dependent on the StringLength attribute (if present)?

    If you specify a [StringLength] validation attribute on a model class, then EF will by default honor that setting when it automatically creates databases for you. You can alternatively specify a custom column sizing using the fluent code API (which I'll probably do a follow-up post on).

    >>>>>>>>> 2. Are enum properties supported on the POCO:s?

    I don't believe they are supported yet with CTP4 - but I believe the EF team has stated publicly that they are coming in a future drop.

    Hope this helps,

    Scott

  • @Andy,

    >>>>>>>> What about change tracking? With this code is EF still able to update a record's changes only? Also, is DbContext thread-safe?

    The EF "code first" approach does support change tracking - so if you retrieve and update a model object it will track the changes and save them back to the database for you when you call "SaveChanges()" on the context object.

    I believe DbContext is not intended to be used from multiple threads concurrently. I'm not 100% certain of that - but believe it is not recommended/supported.

    Hope this helps,

    Scott

  • @Roland,

    >>>>>>>> In an upcoming blog post could you provide an example of EF Code-First that turns out to be a many-to-many relational scenario?

    I will add it to my list and see if I can do this.

    Thanks,

    Scott

  • @Joe,

    >>>>>>>>>>> In the Dinner class you expose the RSVPs as a virtual ICollection.

    >>>>>>>>>>> Can you expose the RSVPs as a virtual IEnumerable or ReadOnlyCollection with a private setter?

    >>>>>>>>>>> This way we could use Add methods such as AddRsvp() instead of exposing the collection's Add method which defeats the purpose of the AddRsvp() method.

    I believe you might be able to do this. You can definitely add custom methods to a model and perform custom logic with them.

    Hope this helps,

    Scott

  • @A,

    >>>>>>>>>>>>>> Does the validation with attributes support multi-lingual?

    Yes - that is fully supported.

    Thanks,

    Scott

  • @colin,

    >>>>>>>> Can I ask what everyone thinks of DinnerID as the name of the primary key? I have always built my Pocos where the ID is just ID.

    The good news is that the "code first" library supports both an approach where you name something like "DinnerID" as the PK - as well as one where you just name the PK "ID".

    Hope this helps,

    Scott

  • @Marcus,

    >>>>>>>>>>> Is there any support for automatic schema changes to an existing database? If a new field is added to the Dinner class is there an automatic way to have EF create the new column instead of dropping and recreating the database?

    We are looking at that scenario right now. We don't have built-in support for that yet - but it is something I know the EF team is hoping to support or make better in the future.

    Hope this helps,

    Scott

  • @David,

    >>>>>>>>> This is great. I'd like to tweak this to use Razor, is there a place to download that other than through the WebMatrix download?

    We'll shortly be releasing the first preview of Razor that works with ASP.NET MVC. Keep an eye on my blog over the next two weeks... :-)

    Thanks,

    Scott

  • @Pete,

    >>>>>>>>>> Is there an underlying feature of EF we can use to generate that schema change and deploy it on production databases separately as part of a more formal process?

    You can explicitly create a database by writing code like below on the DbContext object:

    NerdDinners context = new NerdDinners(connectionstring);
    context.Database.CreateDatabase();

    This can be used to help setup a database programmatically within a production scenario.

    Hope this helps,

    Scott

  • @bladesinger,

    >>>>>>>>>> is it possible to use Interfaces with the POCO classes and is it possible to detach an object pass it through application layers and attach it again.

    Yes - I believe you can do both of these scenarios. I'll try and blog about them in the future.

    Hope this helps,

    Scott

  • @Stacey,

    >>>>>>>>>>> I'd much rather do this so that I fully understand the schema and structure done. But I've yet to see a CodeFirst example that explains how to connect to an existing database.

    You certainly don't need to automatically create the database. You can manually define the database schema as well - that is fully supported.

    Hope this helps,

    Scott

  • @Kishor,

    >>>>>>>>> Does WCF Data Services work with this? Couldn't figure out what to put in my DataService tag.

    Yes - because the models are POCO you should be able to support this scenario.

    Hope this helps,

    Scott

  • @Lynn,

    >>>>>>>>> Scott, last year at the PDC a prototype of ActiveRecord was shown running on top of the previous code-only CTP. Is ActiveRecord something still being worked on? MVC with ActiveRecord would be a major win.

    No - we don't currently have plans to ship that. We are instead focusing on the code-first approach I blogged about here. We think this provides a really clean/easy database story which also provides more power than an activerecord based pattern.

    Hope this helps,

    Scott

  • @Santos,

    >>>>>>>> It will be nice if the metadata could be defined separately (?) like the WCF RIA Services' XmlMetadataProvider or by using a Fluent Interface. That way it'll be easier to incorporate existing POCOs defined in separate assemblies.

    Yes - that is supported. I'll blog about how to do that in the future.

    Hope this helps,

    Scott

  • @andyb.uk,

    >>>>>>>>> The CTP license appears to prohibit Production deployment. This is a shame really. It would be nice to have a licence for the CTPs that allowed use perhaps in Intranet/Extranet/Departmental apps, even whilst knowing that API changes (and some bugs) would be present in the CTP.

    I agree - I just sent mail to the SQL team asking about that.

    Hope this helps,

    Scott

  • @David,

    >>>>>>>> Is there a way around this default functionality (ie I want different names for my dbcontext and connectionstring) ? The closest thing that I can find is a *proposed* addition to DataAnnotations that's not available yet.

    Yep - absolutely. You can override the name of the connection-string by implementing a constructor and calling base with a custom name to use:

    public class NerdDinners : DbContext {

    public NerdDinners() : base("MyOtherNaneToUse") {

    }

    public DbSet Dinners { get; set; }
    public DbSet RSVPs { get; set; }
    }

    Hope this helps,

    Scott

  • @pbz,

    >>>>>>>>>>>>Looks good so far. What I haven't seen in this tutorial is how to add custom attributes to the model that should not be in the database. Also, when a model has a list of entities attached to it (like an Order has a list of Products) can we use IList Products {get;set;} or does it have to be ICollection?

    I'm looking to cover this more in a future blog post.

    Hope this helps,

    Scott

  • @Dominic,

    >>>>>>>> Does this code first approach support more advanced mapping scenarios such as class inheritance mapping and component mapping, for instance if I want to map an Address value type on a Customer entity (as per domain driven design)? Sorry to constantly compare EF to NHibernate but Nhibernate does support these advance mapping constructs, though it's good to see EF catching up.

    Yes you can - I'll cover it more in a future blog post.

    Hope this helps,

    Scott

  • @Bryan,

    >>>>>>>>>> Scott - I hope that the EF4 team is talking to the DB Pro team about Code-First and how it may work with DB Pro. It would be good for MS to have a strategy before the Code First feature ships on how the DB Creation capability would be migrated over to a more sustainable model - I can see reasons to start out using Code First on a project and then at some future maturity point want to leverage the benefits of DB Pro (Data Dude) to manage the DB Schema objects. It sounds like there are plans to mature the EF way of updating databases (perhaps to enable something similar to Rails migration capabilities) - I will hope for a story that includes DB Pro as well because I see Code First being useful for a lot of apps even Enterprise ones initially that down the road will need more rigor - it would be disappointing for that scenario to not be considered. Thanks for all of the great new stuff - keep it coming!

    Agreed - that is definitely something we are looking at.

    Hope this helps,

    Scott

  • Scott, thanks for the clarificaton on Active Record. Very much looking forward to getting in to pre-production with code only this fall. Can't wait to leave behind .edmx! :)

  • It would be great to see some kind of database migration framework built-in ala FluentMigrator, Migrator.NET, or RoR, making it easier to modify the database(s). Sometimes you want that new DateTime field in C# to map to a SmallDateTime column in SQL Server with a GetDate() default value and an index on it, and you need a way to get closer to the DB metal, while still doing the database versioning and change management in code.

  • Great post!

    You might wanna add CultureInfo.InvariantCulture to Date.Parse in NerdDinnersInitializer. Since it gives an error, if your machine isn't set to English.

  • Great post,

    one of the issues for developrs is deploying database within their application. Now by using NE4 and taking advantage of Code-Firs I think it can be very easy to deploy database-depended applications on target machines.
    Do you agree with me Scott?

  • This is what EF should have been in version 1.0. Awesome.

    A few comments:
    1. Why is both RSVP.Dinner and RSVP.DinnerID needed? Is this a requirement? I much rather have just RSVP.Dinner (and the by convention this should create a DinnerId in the RSVPs table). What happens if someone writes RSVP.Dinner = new Dinner() or RSVP.DinnerID = 2. How are the properties kept in sync? If this is a requirement, then at least allow the DinnerID to be private.

    2. Dinner.RSVPs should also allow a private set, so one can not write something like myDinner.RSVPs = new List().

    3. Also I hope Dinner.RSVPs can be of type IEnumerable so one can not write myDinner.RSVPs.Add(...), but instead can be forced to write myDinner.AddRsvp(...)

    3. Finnilay. The official .NET Naming convention says that it should be DinnerId, not DinnerID, and Rsvp not RSVP.

    But still... this is looking very very good. Keep up the good work.

  • Is it possible to have a custom table naming, column naming and primary key naming convention defined? For example we have an existing database that uses 'tb' as prefix for table names such as tbProduct, tbSupplier_Product and the like. For columns we use 'product_name', 'supplier_code' etc. Is there a way in the EF to have this defined in one class/method/configuration as opposed to defined this using annotations all over the database ? If so where can I find the API?

  • Scott, it might be an obvious question, but does this also plug together with ASP.NET Dynamic Data (WebForms) which supports both LinqToSql and Entity Framework? Obviously the validation stuff now works with WebForms DyanamicData, MVC2 and RIA Services (Silverlight, etc).

    So does the EF code first approach (which is now also heavily using the validation metadata), also work with WebForms DynamicData?

    Thanks,

    David

  • Great stuff! Thanks, and big up to you guys !

  • Hello Scott,

    When should the NerdDinners/DbContext class be instantiated ? Should it be a singleton created when the application starts or just when you need it or maybe once per request? I am wondering if it is a heavyweight or lightweight operation ?

    Will it be a problem if the NerdDinners/DbContext class contains 20-30 DbSets ? Should it be split up into smaller pieces instead ?

    Will EF support an Id generator like the HiLo approach to prevent doing a Select (Select Scope_Identity) after each insert and do all in one batch?

    It really begins to look promising.

    What about a property like CreatedAt which should only be set when object is first created and after that not be possible to change ? (Is there an NotUpdate() method which can be used in the configuration of the property? or something like that?).

    I find it unrealistic that you would want to map directly to the poco objects in a real world scenario like you do in the example.


    Thanks

    Martin

  • Minor typo. I think:
    Add->ASP.NET Folder->Add_Data
    Should be:
    Add->ASP.NET Folder->App_Data

  • Small correction: "You’ll need to add a reference to the System.Data.Entity.CTP" should be "You’ll need to add a reference to the Microsoft.Data.Entity.CTP". Your code has the correct reference, of course.

    Question: When is a production-ready version of the CTP going to be release (your estimate if no dates exists)?

    Thanks muchly for this.

  • Looks very promising.
    A way to specify a shadow database connection string would be nice.
    I'm looking for support for the use case where I make changes to my POCOs and do a build. The build would recreate the shadow database, do a diff between the new version of the shadow and the development (or producton) database, generate the up and down delta scripts to migrate the dev (or prod) database and apply the scripts only to the dev database. (the down scripts could be used in case a rollback of code and database is needed in prod)

  • This is the first time I have looked at the Entities Framework as we use an in-house ORM where I work. I have to say it all looks delightfully simple. 2 questions though:

    1. If Dinner and RSVP inherit a base class which includes audit properties (CreatedOn, UpdatedOn etc), is it possible to tell the framework to include these fields in the DB schema?

    2. Can I override SaveChanges to find all updates/inserts and set the audit fields?

  • What a long way back to LINQ TO SQL ;)

  • The ability to have EF automatically migrate changes to existing databases would be outstanding, I hope that happens soon!

    ...Stefan

  • This is awesome!

    FYI - In the first sentence of Step 5, you called it "EF code-only" instead of "Code-First"

  • Great!

    Scott, can we use a smiliar implementation for RIA Services and Silverlight 4? IE, The DomainContext will inherit from DbContext?

    Regards
    Andries

  • Hi Scott,

    RE Database versioning and migration:

    What mechanism do your users use for this? Certainly EF is not just for prototyping (is it?), so what do your large app users use for this with EF? Do they maintain the DB schema manually? What options are there for maintaining DB schemas with EF?

    This has been the only reason for me not to switch to EF since the very beginning.

  • The DbContext derived class will be IDisposable in your controller. You should probably dispose it, moving it to the Index / Create methods would probably be the easiest solution.

    I have played a little with the CTP but I can't get it to attach an object and save its changes. If I make the changes to the object after attaching it will save just fine. But if I change the object then attach the changes won't be saved to the database.

    p.ProductName = "coded first";
    context.Products.Attach(p);
    context.SaveChanges();

  • this is great !
    I just walk throught this post and it works beatufully !
    That´s why MS rocks !

  • Hi Scott -- kudos to all involved for this great leap forward. My question is will it work with SQL Azure as the database? I've been trying to make it work, but hitting dead ends. Here's what I've done:

    1. Got it to run fine against my local SQL Server

    2. Created a NerdDinners database on SQL Azure and recreated the 3 tables that were generated on my local SQL Server up on SQL Azure

    3. Set my connection string as follows to connect to SQL Azure:

    <add name="NerdDinners"
    connectionString="Server=tcp:.database.windows.net;Database=NerdDinners;User ID=@;Password=;Trusted_Connection=False;Encrypt=True;MultipleActiveResultSets=True;"
    providerName="System.Data.SqlClient" />


    4. Ran the app, and get the following exception on this line:

    public ActionResult Index()
    {
    var dinners = from d in nerdDinners.Dinners
    where d.EventDate > DateTime.Now
    select d;

    This operation requires a connection to the 'master' database. Unable to create a connection to the 'master' database because the original database connection has been opened and credentials have been removed from the connection string. Supply an unopened connection.


    Any ideas how to get this to work?

    Thanks so much.

  • Another great post and very exciting developments on this front. Thanks Scott!

  • absolutely love it. def. going to check it out very soon!

  • This looks superb - utterly superb. As a devout Linq2SQL fan, this may be enough to tempt me to jump. Combined with the MVC framework, I think I'm finding a renewed love of web dev - thank you.

  • Well, I didn't managed to make it worked and lost the WCF Ria Service toolkit fonctionality (impossible to see dbml classes while creating a domainservice) but a few uninstall, reinstall later all was back.

    However this sounds great from a building approach - I only wonder if a good usage of T4 - generics - Linq - Cache may not provide a quite easy (POCO) datalayer with really good performance...

    But thanks a lot for this, I start thinking that there will be something to code with ET4.

  • Will cross-context linking be possible at all? For example, what if I want one data context for User data and another for Project data. This would be useful so that if I needed to I could put user tables on one db server and project data on another db server for better load balancing. While this could technically be feasable now just using IDs and no explicit links, having a fluent construct that tells the Project context that Project.User comes from the User context could be very useful I think.

  • Would like to see an example of connecting to an existing db schema. I know this violates the idea of "code-first", but the reality is that I want to use POCOs and the simplicity of the code-first DbContext and DbSet classes against some tables which already exist (and in some cases have EF add tables and make changes where appropriate).

  • Its really nice post.. It save lot of development effort.

  • @Mike

    The StoreIgnoreAttribute is planned for the next release of Code First. Enum support will be added in as a full Entity Framework feature and will be available with the next major release of the .NET Framework so stay tuned, it's all coming :)

    Thanks for trying this out and for the feedback!

    Jeff Derstadt
    Entity Framework & Code First Team

  • Hi great article and re: "It works with VS 2010, and you can use it with any .NET 4 project (including both ASP.NET Web Forms and ASP.NET MVC)." I've just found that it will work with ASP.Net Dynamic Data EF Template see here Using Entity Framework Code First (CTP4) in Dynamic Data

    Steve

  • Oops that url didn't quite work (no allowing me to embed an a tag :( ) http://csharpbits.notaclue.net/2010/07/using-entity-framework-code-first-ctp4.html this will

  • @Andrew Gunn,

    >>>>>>>> Great article! Quick question: can EF utilise the power of TVPs (table value parameters) when calling stored procedures?

    Sadly, no. In order to use TVPs you need to drop down to core ado.net—we don’t have any higher-level support in the EF. If you do use core ado.net to do it and get back a DataReader, though, then you can use Translate to transform results from the sproc into entities or the like…

    Hope this helps,

    Scott

  • @Rangoric

    >>>>>>>> Is there any way to work with geometry and geography types with this or is that still not doable yet?

    Unfortunately the geo-spatial types in sql server aren’t supported in EF4. It is something we are looking to enable in the future though.

    Sorry!

    Scott

  • Thanks for a great post!
    So, what is the guidance if I am working with SQL Server (rather than SQL Express or CE)? Say, I have the database, but I would like code-first to generate the tables. I tried to just put connection string in web.config - but it gave an error (is it supposed to work and I am doing something wrong? or it is not expected work for SQL Server?)

    Should I use CreateDatabase() and then remove it? Or is there a way to generate sql that I can run against the database?

    What's the best approach?

  • Great tutorial. I am really enjoying using Code-First.

    Just tried to implement an override of RecreateDatabaseIfModelChanges in the same way as you did in NerdDinnersInitialiser, but I think you might have missed "context.SaveChanges();" once you had added all the dinners.

    Thanks Scott

  • This looks just great.
    Looking forward for the data migration capabilities.
    Cheers!

    Gerardo

  • Scott,

    This is really good stuff. Entity Framework is shaping up very nicely! finally.

    A few comments:
    I have a security concern with user account rights, since it needs full(sql dba) level permissions to create database, access to master database and to sync changes model vs table.

    Is it another kind of sql injection and other issues?

    Production environments are allowed to use data access and definitely not dba level permission.

    This is a big real concern as a security point.

    But still... this is looking very very good. Keep up the good work.

  • How about a channel 9 video ?!?!

  • Scott,
    One small problem. During the creation of Create.aspx, my Add View dialog had the View Content dropdown disabled. Not sure if this is cause for alarm or not. Any ideas on why that would be the case?

    Thanks,
    Nick

  • Scott, This is great stuff and a very informative post but I have hit a road block that I can't figure out. I am trying to use this with a SQL 2008 db & using a data context that implements ObjectContext like so:

    public class DataContext : ObjectContext

    And then in my constructor I am passing a named connection string to the base like so:

    public DataContext() : base("name=TestDB", "TestDB") {}

    My connection string is in the web.config and loks like this:



    However when I try to run this I get the following exception:

    "The specified named connection is either not found in the configuration, not intended to be used with the EntityClient provider, or not valid."

    Anybody have any thoughts?

    Thanks, --Jim

  • Jim I think your connection string name and initial catalog have to be the same. Try that.

  • Noel, I thanks for the idea but same error.

  • @bidel
    >is it the beginning of "goodbye nhibernate"?
    Maybe!

    Scott/Jeff, can we use Guids or other data-types as PK?

  • Thanks for a great post.

    If the database i am using is SQL Server 2005, and I map the DateTime type in .NET framework to a cell of type "datetime" (in SQL), it gives an exception that
    "SQL Server 2005 does not support datetime2 data type"!!!!

    I used the Entity Framework released in .NET 3.5.

    Is there any way to work around this hurdle????

  • @David Boike

    As stated by the team and others, enums are not supported. You posted a link to your blog post which incorrectly states that they do work and that you've tested it.

    If you add an enum to a model class, it WILL create the correct column on the table (which is what are observing). But if you attempt to use the model through the data context, an error is thrown. It is not supported, so it's misleading to say it works just because the column gets created.


  • Has anyone tried using this with WPF? I have a desktop app that I'm going to be working on, and would like to do in WPF, and this would save me quite a bit of work, assuming of course that it's going to be ready for production in the next 10 months or so.

  • @David

    Yes, you can use Guids and other data types as PKs. A Guid will map to a "uniqueidentifier" on SQL Server. Also, remember that if you name your property something that doesn't have "ID" in the name, you can use the [KeyAttribute] on that property to make it part of the primary key.

    Jeff
    Entity Framework/Code First Team

  • @Manish

    I can double check to make sure we don't have a bug in our SQL Server 2005 provider because you should see a regular "datetime" and not a "datetime2" type when the database is generated. In the time being, you can set the store type that is used in your DbContext's OnModelCreating overload:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
    modelBuilder.Entity()
    .Property(e => e.ModifiedDate)
    .HasStoreType("datetime");
    }

    Jeff
    Entity Framework/Code First Team

  • @Jim - it almost sounds like your have the wrong .dll referenced. Make sure that it is the Microsoft.Data.Entity.CTP.dll.

  • Great post! Thank you very much.

    But I'd really like to know, if there's any possible way, to define cascade on delete?

  • This really looks powerful. I've Loaded the sample, and it worked well after I got the right versions of the dependencies.

    Could you post sample connection string for MySql and SqlExpress. You said that it works best with database provider you used. Does it actually work now with the other two?

  • @nhaydon - I just checked and I am using Microsoft.Data.Entity.CTP.dll v4.0.30319.0. Thanks.

  • Good. But you still need to go tweak sql data types in your database schema. Our company prefers poco generation off the EF model. Works for us.

  • Hi,
    I created a entity model from the existing database but all the table names contain "_"/underscore in the name so while creating poco classes i want no underscore in the name of the tables. Is there a way to change the naming convention while the entities are created in the entity framework

  • Hi, great article,
    one question : are nullable properties supported in the POCO Classes ?
    Thanks
    Cedric

  • I have changed up my method of doing this to use a DbContext like the demo above. But I can't figure out how you enable lazy loading when using a DbContext?

  • Hi Scott, this looks great. What's your opinion on writing unit tests agaainst the seeded SQL CE database instead of something like an in-memory repository?

  • h,

    Awsome article. Please tell whether the same way can be used aCROSS DIFFERENT TYPES OF DATABASES ?

    tHANI

  • Hi,

    I'm getting the same error as Steve Harshbarger, but I'm using SQL Server 2008

    "This operation requires a connection to the 'master' database. Unable to create a connection to the 'master' database because the original database connection has been opened and credentials have been removed from the connection string. Supply an unopened connection."

    Any ideas?

  • I'm noticing if you were to add a RSVP in the above method by creating a RSVP object and just assigning it the DinnerID and not using Dinners.Add(new RSVP()). After you save back to the repository you will get a RsvpID for your object however, you won't have a System.Data.Entity.DynamicProxies.Dinner link back to the dinner. I know in this example its silly, but what if you had a RSVP type or something? How do you create a new RSVP for a dinner and set the type of RSVP? (if this rsvp type existed)?

    Thank, always enjoy your blogs. Thank you for all the work. I have no idea how you find the time.

  • Ok. I got the same issue as Colin.
    I'm also running on SQL 2008.

    The config file contains a connectionstring to our remote sql 2008 server, that uses sql authentification with User Id and Password.

    1. The connection CAN be established
    2. The database CAN be dropped.
    3. The database CAN be recreated.
    4. And then it fails, every time.

    the exact message is (as stated before):
    "This operation requires a connection to the 'master' database. Unable to create a connection to the 'master' database because the original database connection has been opened and credentials have been removed from the connection string. Supply an unopened connection."

    For me this happens when i force a recreation of the database by calling:
    context.Database.DeleteIfExists();

    The same thing works with no issues when using the local SQL 2008 and integrated security.

    Anyone having similar issues?

  • Hi,
    Great Article. Thanks Scott. Please keep posting such articles on Entity Framework.

  • KACF (Kick Ass Code First)!

  • Nice article. Thank you.

  • Superb simply Magnificent piece of Code

  • Will other databases be supported?

  • Very cool article, thanks.

  • Great Article. Please let us know how can we use this on our server Thanks Scott.

  • code correction for adding new dinner:
    nerdDinners.Dinners.SaveChanges();

  • Just did a one-up on Hibernate and the Java camp. Great job MS!

  • A number of people mentioned problems with the following error:

    "This operation requires a connection to the 'master' database. Unable to create a connection to the 'master' database because the original database connection has been opened and credentials have been removed from the connection string. Supply an unopened connection."

    I had this error and solved it by adding "Persist Security Info=true" to the connection string.

  • How to add custom property in association table in case of many to many relation

  • This is some seriously cool technology..

    Love it!

  • This is great stuff, I love it... keep it up! I do have one question though. Why can't I see my .sdf file in the AppData folder? The code works... it is storing and retrieving data, but I don't know where the db is located. I even searched my machine for all .sdf files and couldnt find it. I'm on VS2010 Ultimate with CTP 4 and SQL CE 4. Any ideas?

  • If we use an existing database it says that the model has changed and u have an option to delete everything.
    Can't this code first merge it's new tables with an existing database ?

  • Found the answer to my question. It is putting the DB in SQLExpress, I was looking at the wrong web.config file.

Comments have been disabled for this content.