According to Microsoft, the Entity Framework is the preferred method of data access
for .NET applications, supporting strongly-typed access through LINQ. The Entity
Framework also allows developers to program against a conceptual model that reflects
application logic rather than a relational model that reflects the database structure.
The Entity Framework can also be used from an ASP.NET application through the
Entity Data Source.
EF4 now offers what developers have been screaming for - the ability to generate
the back-end database schema from a POCO - based model that you design first
- also known as "top down" development.
In order to facilitate this, Diego Vega of Microsoft has put together the ADO.NET C# POCO Entity Generator, a T4 template that is actually two templates - one called <YourProject>context.tt,
and the other <YourProject>.tt. There is a complete listing of the various templates here.
The “<YourProject>.tt” file is responsible for generating a file for each EntityType
and ComplexType in your "MyProject.edmx” model.
The second template (“<YourProject>.Context.tt”) produces a strongly typed
ObjectContext for the “edmx” model. You use this strongly typed ObjectContext
to interact with your database.
By splitting the template into two, one part that generates the Entity Types and
Complex Types and one that generates a strongly typed context, it makes it possible
not only to have Entities and ComplexTypes that are persistence ignorant but
in addition to be able to site those classes in an assembly / project that has
no persistence aware code in it at all. This is the model preferred by your "POCO
Purist". To do this, one only needs to move the entities into a separate
class library project, and move the <YourProject>.tt file into the new
library project. Lastly, you need to "Fix" the link in the Template
to point to the edmx model's new relative location, e.g. change
string inputFile = @ “MyProject.edmx” ;
To:
string inputFile = @ “..\MyMainProjectFolder\MyProject.edmx”;
Once this is done, you can have a class library that contains only persistence-ignorant
entity classes, which will be used by the generated ObjectContext in the main
project. Finally, you'll need to change the namespace where the context template
expects to find your entities. You can do that easily by bringing up the Properties
dialog for the .Context.tt Template and in the "Custom Tool Namespace"
item, enter in your "Entities" namespace or whatever namespace you
chose for your entities class library project. When the Template files are saved,
the solution should build correctly.
Up until Entity Framework 4.0 I preferred the POCO top-down model so much that I
would only use NHibernate, which easily supports it along with Fluent.NHibernate
to facilitate reflected code - only mapping and configuration. But the idea of
being able to design one's entity model directly on a nice Microsoft - engineered
designer canvas that is already built in to Visual Studio 2010 certainly has
its appeal.
In my example here, I don't do any of this entity separation as it is not difficult
to do, and I wanted to keep everything super simple in order to illustrate the
POCO alternative. I have a very simple Notes application with only two classes,
Note and Category. This is what you design on an empty Entity Framework design
surface:

The Association between Note and Category means that a Category can contain any number
of Note instances, and a Note can only have one selected Category. Note that
the designer adds a nice Navigation Property to each class that allows us to
lazily load these objects on demand.
When you set up your Guid Id properties, it is important to set the StoreGeneratedPattern
values to "None" - since we are supplying our own fresh Guids on our
new entities that will be saved.
Once your model is designed, you can right-click on a blank spot in the design canvas
and choose "Generate Database from Model", and bazoom - all the SQL
for that provider is generated. Bring up the YourProject.edmx.sql file, right-click
inside it and choose "Execute SQL" and you're done!
I'd be interested to see when Robert Simpson finds the time to update his ADO.NET SQLite Provider to match this new top-down
model. You can use SQLite with Entity Framework 4.0 - you just cannot do top-down
-- yet!
If you change your entity model, just regenerate the new backend SQL the same way.
The onlly thing it does not do is create the database for you - you need to do
that first and specify it with a new DataConnection.
Finally to get the entire POCO model working and get your generated entity classes,
you need to right-click the designer and choose "Add Code Generation Item",
and choose "ADO.NET POCO Entity Generator". This will generate your
entity classes from the model that you designed.
That's all it takes. Now you can develop against your model and context. I have a
simple Windows Forms app that lets you add a Category (which then appears in
the Categories dropdown), and Add a Note. There are also two buttons to display
your Notes either by selected date from a DateTime Picker, or via the Category
that you have selected from the dropdown. Some example code is illustrated below:
private void btnAdd_Click(object sender, EventArgs e)
{
using (EF4POCONotes.Model1Container context = new Model1Container())
{
Category cat = new Category() {CategoryName = txtCategory.Text, Id = Guid.NewGuid()};
context.Categories.AddObject(cat);
context.SaveChanges();
this.cboCategory.DataSource = context.Categories;
}
}
private void btnAddNote_Click(object sender, EventArgs e)
{
Guid catId = (Guid) ((Category)cboCategory.SelectedValue).Id;
using (EF4POCONotes.Model1Container context = new Model1Container())
{
Category category = context.Categories.Where(c => c.Id == catId).FirstOrDefault();
Note note = new Note() {Id=Guid.NewGuid() ,CategoryId=catId,EntryDate = dtpEntryDate.Value, NoteText=txtNoteText.Text,
Category=category ,Subject=txtSubject.Text};
context.Notes.AddObject(note);
context.SaveChanges();
this.cboCategory.DataSource = context.Categories;
}
}
private void Form1_Load(object sender, EventArgs e)
{
using (EF4POCONotes.Model1Container context = new Model1Container())
{
this.cboCategory.DataSource = context.Categories;
}
}
private void btnDisplay_Click(object sender, EventArgs e)
{
using (EF4POCONotes.Model1Container context = new Model1Container())
{
// give a range selected from the datetimepicker selected value
DateTime beginDate = dtpEntryDate.Value.AddDays(-1);
DateTime endDate = dtpEntryDate.Value.AddDays(1);
List<Note> notes = context.Notes.Where(n => n.EntryDate >beginDate && n.EntryDate<endDate ).ToList();
Form2 frm = new Form2();
frm.Notes = notes;
frm.ShowDialog();
}
}
private void btnDisplayCategory_Click(object sender, EventArgs e)
{
using (EF4POCONotes.Model1Container context = new Model1Container())
{
// Get the notes for this category
List<Note> notes =
context.Categories.Where(c => c.Id == ((Category) cboCategory.SelectedItem).Id).FirstOrDefault().
Notes.ToList();
Form2 frm = new Form2();
frm.Notes = notes;
frm.ShowDialog();
}
}
Entity Framework 4.0 has a lot of improvements over the previous version, and this
is only one of them. You can download the completed solution here. Be sure to download and install the T4 Template from the link above, and be sure
to check your connection string as I use SQL Server developer for all my work,
not SQLEXPRESS. Create a new DataBase "EF4NOTES" and create a DataConnection
to it in Server Explorer, and you should be good to go.