The information in this post is out of date.
Visit msdn.com/data/ef for the latest information on current and past releases of EF.
For Model First see http://msdn.com/data/jj205424
For Database First see http://msdn.com/data/jj206878
This post will provide an introduction to Model First and Database First development with the DbContext API, using the Entity Data Model Designer in Visual Studio.
You will need to have Visual Studio 2010 or Visual Studio 11 installed to complete this walkthrough.
1. Create the Application
To keep things simple we’re going to build up a basic console application that uses the DbContext to perform data access:
- Open Visual Studio
- File -> New -> Project…
- Select “Windows” from the left menu and “Console Application”
- Enter “ModelFirstSample” as the name
- Select “OK”
2. Create the Model
Let’s go ahead and add an Entity Data Model to our project;
- Project –> Add New Item…
- Select ‘Data’ from the left menu
- Select ‘ADO.NET Entity Data Model’ from the list of available items
- Name the model ‘PersonModel.edmx’
- Click ‘Add’
We are going to use Model First for this walkthrough but if you are mapping to an existing database you would now select ‘Generate from database’, follow the prompts and then skip to step 4.
- Select ‘Empty model’
- Click ‘Finish’
Let’s add a Person entity to our model:
- On the design surface; Right Click –> Add –> Entity
- Name the entity ‘Person’
- Click ‘OK’
- On the Person entity; Right Click –> Add –> Scalar Property
- Name the property ‘Full Name’
3. Create the Database
Now that we’ve defined the model we can generate a database schema to store our data:
- On the design surface; Right Click –> Generate Database from Model
- Click ‘New Connection…’
- Specify the details of the database you wish to create
- Click ‘OK’
- If prompted to create the database; click ‘Yes’
- Click ‘Next’ then ‘Finish’
- On the generated script; Right Click –> Execute SQL…
- Specify your database server and click ‘Connect’
4. Swap to DbContext Code Generation
The PersonModel is currently generating a derived ObjectContext and entity classes that derive from EntityObject, we want to make use of the simplified DbContext API.
To use DbContext we need to install the EntityFramework NuGet package:
- Project –> Add Library Package Reference…
- Select the “Online” tab
- Select the “EntityFramework” package
- Click “Install”
Now we can swap to using DbContext code generation templates:
- On the design surface; Right Click –> Add Code Generation Item…
- Select ‘Online Templates’ from the left menu
- Search for ‘DbContext’
- Select ‘EF 4.x DbContext Generator’ from the list
(If you are using EF 5 you should select ‘EF 5.x DbContext Generator’ instead) - Name the item ‘PersonModel.tt’
- Click ‘Add’
You’ll notice that two items are added to your project:
- PersonModel.tt
This template generates very simple POCO classes for each entity in your model - PersonModel.Context.tt
This template generates a derived DbContext to use for querying and persisting data
5. Read & Write Data
It’s time to access some data, I’m padding out the Main method in Program.cs file as follows;
class Program
{
static void Main(string[] args)
{
using (var db = new PersonModelContainer())
{
// Save some data
db.People.Add(new Person { FullName = "Bob" });
db.People.Add(new Person { FullName = "Ted" });
db.People.Add(new Person { FullName = "Jane" });
db.SaveChanges();// Use LINQ to access data
var people = from p in db.People
orderby p.FullName
select p;Console.WriteLine("All People:");
foreach (var person in people)
{
Console.WriteLine("- {0}", person.FullName);
}// Change someones name
db.People.First().FullName = "Janet";
db.SaveChanges();
}Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
Summary
In this walkthrough we looked at Model First and Database First development using the DbContext API. We looked at building a model, generating a database, swapping to DbContext code generation and then saving and querying data.
Rowan Miller
Program Manager
ADO.NET Entity Framework
Why not include how to remove a row in this tutorial? For me that's the next logical step.
Remove an entity:
using (var db = new MyEntities())
{
var entity = db.EntitySet.Single(b => b.SomeIdentifier == id);
db.EntitySet.Remove(entity);
db.SaveChanges();
}
Sorry, but this does not work. I have followed the step-by-step instructions with one table from an existing database and it does not generate a PersonModelContainer as used in the last step. I have tried EF4.3.1, EF4.3 and EF4.2. Is there something I am missing?
Thanks
@Tim – The name of the context will depend on what you called the connection string when you reverse engineered from the database. If you right-click on the design surface of your model and select 'Properties…' there will be an Entity Container Name property that will tell you what the context is called (you can also change it if desired).
I see no EF 5.x generators yet. You mention them and I was wondering if it's fine to use the 4.x generators?
@Tim The EF 5.x DbContext generators are available if you are targeting .NET 4.5 on VS 11. If you are targeting .NET 4 then you should use the 4.x generators for now. Updated 5.x generators that will work with .NET 4, .NET 4.5, VS 2010, and VS 11 will be available soon.
Hi,
Does ADO.NET Entity Framework support web base DB CRUD generating/operation?
Thanks
@semetah – Are you asking about exposing CRUD operations over the web? If so then WCF Data Services and Web API are two technologies that work nicely with EF to achieve this.
Thanks Rowan, is there a demo site, or tutorial, or documentation for building CRUD operations over the web using WCF Data Services and EF Web API?
Thanks
@semetah – You can find info about Web API here; http://www.asp.net/web-api. The current preview doesn't automatically scaffold controllers with logic to interact with an EF model but that is coming in their next release. This article & video cover using WCF Data Services with EF; msdn.microsoft.com/…/hh272554.
Hello,
I think your article misses a 'system requirements' section, I followed exactly the steps described and a DbUpdateException (Server-generated keys and server-generated values are not supported by SQL Server Compact.) occurred, using SQL CE 3.5. For people who are willing to use it, the person Id should be set as well.
Sorry I talked too fast … even when setting an ID, CE 3.5 does not work at all (correct me if that's wrong), 4.0 works but there's a trick. to make it work : stackoverflow.com/…/entity-framework-4-and-sql-compact-4-how-to-generate-database
4. step doesn't work in VS 2011, any idea?
None of the DbContext Generator are in the list…
@uesendir – Are you looking on the Online tab?
Where does the "People" in
db.People.Add(new Person { FullName = "Bob" });
come from??
Shouldn't it be called:
db.PersonSet.Add(new Person { FullName = "Bob" });
I followed the example, as much as possible (i don't have a Project->Add Library Package Reference… but instead used the Project -> Manage NuGet Packages… (i assume it's the same) to add the EF 4.3.1)
I don't have a People class.
I used VIsualStudio 2012 & EF 4.3.1
Sorry i've obviously NOT used VS 2012 🙂 but Visual Studio 2010 Pro
@Jan – People isn't a class but rather a property of the context. You actually get to choose the name when you add the entity to the design surface (but by default it will calculate the plural of the name you give the entity).
Rowan, are you there? I need some help.
I need to learn to set up good unit tests to DbContext using Moq.
I followed the steps here:
blogs.msdn.com/…/productivity-improvements-for-the-entity-framework.aspx
The t4 template generated a DbContext context class. I edited and changed DbSet to IDbSet.
I extracted an interface. I added all the public properties and methods from the DbContext class.
Then I mock this super interface.
This gets me some decent looking code that builds, but it does not run.
public partial class PosManContext : DbContext, IPosManContext
{
public PosManContext()
: base("name=PosManContext")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public IDbSet<note_template> note_template { get; set; }
}
public interface IPosManContext
{
DbChangeTracker ChangeTracker { get; }
DbContextConfiguration Configuration { get; }
Database Database { get; }
void Dispose();
DbEntityEntry Entry(object entity);
DbEntityEntry<TEntity> Entry<TEntity>(TEntity entity) where TEntity : class;
bool Equals(object obj);
int GetHashCode();
Type GetType();
IEnumerable<DbEntityValidationResult> GetValidationErrors();
int SaveChanges();
DbSet<TEntity> Set<TEntity>() where TEntity : class;
DbSet Set(Type entityType);
string ToString();
IDbSet<note_template> note_template { get; }
}
unit test code:
Mock<IPosManContext> posManContext;
posManContext.Object.Set(typeof(note_template));
posManContext.Object.note_template.Add(
new note_template()
{
note_template_id = 1,
act_flag = "Y",
desc_text = "Monday Monday",
last_update_dtm = now,
last_update_user_id = "hsimpson",
});
I get an error that the DbSet is null.
Microsoft needs to provide a good example of what to do for unit test using mocking.
They went half the way by providing public interfaces for mocking, but I still need more help.
Joe
@Joe Kahl – The note_template property is returning null because you haven’t set it up to return anything in the mocked context, you would need to create a mock of the DbSet and then setup the note_template property to return that mock. Here is some documentation on getting started with Moq – code.google.com/…/QuickStart.
If you are still running into issues then please start up a http://stackoverflow.com/ thread and tag it with ‘entity-framework’ and ‘moq’.
Found a little bug for the .tt Wizard. (Microsoft.Data.Entity.Design.VisualStudio.ModelWizard.AddArtifactGeneratorWizard)
When you add the .emdx file as a link from another project in another solution, the $edmxInputFile$ in the .tt templates gets replaced properly, so with the relative path "…." etc, but when you add the .edmx file as a link from another project in the same solution the $edmxInputFile$ doesn't get a relative path and an exception is thrown.
Not sure if one would even need to do this, but it shouldn't crash at least.
Thx.
This doesn't really showcase any differences with DbContext compared to the default ObjectContext model. I re-created this tutorial following every step except for adding the DbContext package, and the code worked exactly the same except I had to write db.People.AddObject(new Person …) instead of db.People.Add(new Person …).
@Jorris – I've opened a bug to track this – entityframework.codeplex.com/…/450
@Moozhe – The advantages of DbContext really surface when you start using you model to do more than just add a single object. Although it is certainly easier to find the Add and SaveChanges methods on DbContext (ObjectContext will give you 50+ members to sift through in IntelliSense).