Beginners Guide to Entity Framework

The Essentials
The Entity Framework bridges the gap between how developers commonly manipulate conceptual objects (customers, orders, products; posts, tags, members; wall posts, private messages, friend connections) and the way data is actually stored (records in database tables). The technical term for a tool that provides this abstraction is object relational mapper (ORM). ORMs help developers be more efficient and focused, since they don't need to spend brain cycles thinking about how to communicate with the database. It also means that the code is more portable – switching database software requires changing a setting in the ORM, not a rewrite of the whole codebase to match the new database's dialect. As someone who has programmed using the ORM in Django, I can tell you how such a tool makes development less tedious and more enjoyable when you don't have to consider SELECTS and INSERTS. In fact, I've never before written a line of SQL, yet I was able to build a rich web application thanks to an ORM.

Getting Started
One of the nice features of using the Entity Framework is its out-of-the-box simplicity. To my pleasant surprise, I didn't need to download, install, or patch anything to get started with my first EF app. I booted up VS 2010, opened a new project, designed my entities, wrote my code, and off I went. You can probably get a very simple app up and running in about 10 minutes. To prove it, I'll do exactly that as a step-by-step walkthrough below. For this example, I'll make a simple events calendar.

Begin by opening Visual Studio 2010.

From the 'File' menu select 'New' >> 'Project'. I‟ve chosen Visual C# as my language and a Console Application as my format for simplicity. I will accept the default sequential naming that gets filled in for me, "ConsoleApplication2," so you can follow along by matching this with what gets filled in for you, too, though any real application should have an actual descriptive name such as "EventCalendar" or "PayrollProcessor."

Visual Studio will now set you up with a basic C# application. You may wish to rename the file from 'Program.cs' to something more meaningful to your project, but once again I'll stick with the default names so you can sync up and provide your own in its place.

The next step is adding your entities to the project. To do this, we‟ll need to add a new file to our project which will contain the specifications for our entities. Open up the Solution Explorer panel. (If it‟s not already in your workspace, you can bring it up by 'View' >> 'Solution Explorer'.) Right-click on the name of your application, in my case “ConsoleApplication2,” and click on the option 'Add' >> 'New Item'. Then, select 'ADO.NET Entity Data Model'. A good naming convention for your data model is to append the word "Model" to the end of your database name or application name, such as "EventCalendarModel" or "HumanResourcesModel."

If there was already a database in place that you had to use, then you would select the 'Generate from database' option, and the Entity Framework would do its best to create models and associations that fit the data. If you are starting an application from scratch and get to design the database, as I‟ll be demonstrating in this walkthrough, select 'Empty model.' This is known as the model-first approach, instead of the database-first approach.

This will now open a new file – a canvas onto which you can design your data model. Rather than having to directly write the underlying XML file to specify the models and properties, this designer is a pretty slick way to configure your models and associate them. You start with an empty canvas.

Begin by adding you first entity. To add an entity, right-click on the design surface (the white canvas area) and click 'Add' >> 'Entity' from the context menu. As I mentioned before, I‟m going to use an events calendar as my sample. We will have Users and Events as our two entities. Type a name for the entity, and notice how it automatically attempts to pluralize it in the EntitySet field. EntitySets are collections of entities (that map to tables in the database), which allow you to add, delete, or update entities (rows in the database). In other words, you'll be using this often in your code. Although the system usually gets the pluralization right, you can tweak it as you please. You can leave all of the other settings as their defaults to continue, unless you have a special need to customize them.

The new entity you created will now appear on the design surface. You can drag it around the designer as you please.

The next step will be to add properties to that entity. Properties are essentially "instance data" in the lexicon of object-oriented programming or "columns" in database parlance. You can add a property to an entity by right-clicking the entity and selecting 'Add' >> 'Scalar Property'. When you add the property, you can then name it whatever makes sense.

I‟ll name the first one “Title” – the title of the Event. When you have one of the properties highlighted – while renaming it – you can simply press the 'Enter' key to keep adding more.

Notice how I left out one pretty important "property" – the Event's creator. That's because I plan to keep track of information about each User and which Events he creates, so a User of the calendar will be it's own entity that is associated with Events the User created. This type of property is called a 'navigation property'. As above, I add the User entity by right-clicking the canvas and clicking 'Add' >> 'Entity'.

I‟ll now add two properties to it as above: a username and a password.

Finally, I'll add an association between the Event and the User to represent which User created an Event. To do this, right click anywhere on the design surface and select 'Add' >> 'Association'.

To configure the association: 1. Select the two “ends” of the association, or the two entities you will be associating, and their multiplicity to match the association you have in mind. In this case, I am setting up a many-to-one association between an Event and its creator; each Event has only one creator, but each User may have created many Events. 2. Since you may have multiple associations between the same two entities, it‟s a good practice to be specific about the association name rather than just using the two entity names. I‟ll name this “EventCreator” to be specific about what this association represents and avoid collisions or ambiguity. 3. Customize the navigation properties using terms that make sense relative to this relationship. Rather than just „User‟ and „Events,‟ I‟ll use the terms „Creator‟ and „CreatedEvents.‟ These are the property names used by one entity to get to the other. You would use Event.Creator to get the single User who created that event and User.CreatedEvents for a list of events created by a certain User.

Click OK to create the relationship, and you will see this new linkage appear on the design surface. Notice how the multiplicity of the relationship is represented by the number 1 and the *, one and many, respectively. Also see how the new navigation properties have been added to each entity with the names specified.

To demonstrate why it makes sense to be specific with names of relationships and navigation properties, I‟ll go one step further and allow Users to add Events to their personal calendar. I will keep track of this by a many-to-many relationship, a second association between an Event and a User. Here‟s how that will look:

The extra association appears on the design surface, and the new navigation properties have been added to each entity. Notice how being specific with the naming of the navigation properties makes it very easy to understand – and use – the models, especially when there are multiple associations between the same two entities.

Now I will go through each scalar property I added before and verify that it has the right attributes. Right-click on any property of an entity and click the 'Properties' menu button. This will bring up the 'Properties' panel. Since I‟ll be using this panel consistently while I make these tweaks, I decided to pin it to the right of my workspace by clicking the pushpin icon.

Although there's a lot to see in the properties panel, the most important parts right now are the 'Nullable' and 'Type' options specific to that property. I leave the other settings to a more advanced guide.

If you are using an ORM because you have limited database experience, then the term 'Nullable' may need some explanation. A property that is nullable is one that can contain a 'null' value. For example, if 'description' for an Event is optional, then it could be nullable (set this property to 'true'). If, however, you want to require that every Event must have a time, that field should not be nullable (false). In some senses, the word "optional" can be used as a loose analog.

The 'Type' property should be fairly familiar to a programmer – it's just the data type. So a time is probably best represented as a DateTime type, and an ID number is best stored as a 32-bit integer. One nice feature of the Entity Framework is how it abstracts the database underneath. Whereas one database may require a String, another may require that it be called a VarChar. When using the EF, this minor annoyance is abstracted by the database provider.

For this simple example, I have chosen to first add all of the names of the properties to each entity and

then return to specify the type and nullability. You can also pause at any time while adding entities or properties to entities to do this.

Each property defaults to a string type. In this example, I've gone through and modified only the 'Time' property of the Event to make it a DateTime type. For all of the others, the default to string (or Int32 for keys) was appropriate.

Now my entities are ready, so it's time to ready the database and start writing code. Right click the canvas and select 'Generate Database from Model.'

From here, select the database connection you'd like to use, or select 'New Connection…'. I'll make a new connection in this example. The specifics of getting your database up and running are beyond the scope of this walkthrough. I happen to be borrowing a colleague's server. One notable feature I will cover is that you can specify a database name in the 'Select or enter a database name' field, and it will create a new database on the server for you if it one with that name does not already exist and you have

the proper permissions. Note that clicking 'Test Connection' when you've specified a new database name (one to be created) will fail, since the database doesn't exist yet. Simply press 'OK' to establish the connection and attempt to create the database.

If creating a new database, you should see this dialog box:

Click 'Yes' to try to make the new database on the server. Assuming you've succeeded, you'll return to the original Generate Database Wizard and resume setting it up. The connection string, which tells the EF how to connect to the database, should be filled in for you. Click 'Next' to proceed. Make note of the value in the bottom field, which in my case is Model1Container. This will be needed later in the code to communicate with the database by forming a context.

After it's done thinking, you'll have a DDL file ready to go. Don't get tripped up by the term DDL; all we care about is that this file contains instructions for the database that will get it set up so that you can use your models with it.

This file contains the script that is appropriate for your database to set it up. Click 'Finish' to save that file. It will subsequently open up in VS, and may indicate that it is not connected to the database yet. The next step is to make that connection and run the script. Right-click inside the document and select 'Execute SQL'. Since I'm using SQL Server 2008, the window below pops up and I follow the steps to run the script. Depending on your database, what you have to do to execute that script may vary. After the operation is complete, you'll get a confirmation that it was successful.

At this point, the database is all ready to go, and it's time to start interacting with it via code. Here‟s a code snippet you can run if you were following along.

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication2 { class Program { static void Main(string[] args) { /* In order to communicate with the database using the EF, * set up a context as in the line below. Notice how 'Model1Container' * follows through to here from where I mentioned it above. In order * to interact with data from the database in any way, you must establish * a context. */ using (Model1Container context = new Model1Container()) { /* One way to create a new entity is to give it all of its * values right away as below. Use the entity names from * your model, and assign the properties that you can. */ User mike = new User { Username = "mike", Password = "123456" }; Console.WriteLine("Users before add: " + context.Users.Count()); // 0 /* Notice how the new user does not get added to the database or the context yet */ context.Users.AddObject(mike); Console.WriteLine("Users before save: " + context.Users.Count()); // 0 /* At this point, the context knows about 'mike', but it hasn't yet * saved 'mike' to the database. */ context.SaveChanges(); Console.WriteLine("Users after save: " + context.Users.Count()); // 1 /* Now 'mike' has been saved to the database. Any changes to 'mike' from * this point forward will not be saved until context.SaveChanges() is * called again. */ /* Here's an alternate approach to adding a new entity. * You can continue assembling the entity at various parts of the code. * Warning: Don't try to save an entity if one of its properties has not * yet been set and that property is not nullable. */ User matt = new User(); matt.Username = "matt"; /* If you tried to save here, before setting 'Password', you'd get an error, * since Password is not a nullable field. */ matt.Password = "654321"; context.Users.AddObject(matt); context.SaveChanges(); /* Now it's possible to add an associated entity */ Event bbq = new Event { Title = "Barbeque", Description = "BBQ at the office", Time = new DateTime(2010, 07, 04, 18, 0, 0), Location = "1 Microsoft Way, Redmond", /* The simplicity in the following line is EF magic at work; * setting up an association is effortless, despite the extra * work done in the database for such a relationship */ Creator = mike }; context.Events.AddObject(bbq); context.SaveChanges();

/* Here, too, a many-to-many relationship becomes simple to establish * despite the extra work being done in the database to organize this */ matt.ConfirmedEvents.Add(bbq); context.SaveChanges(); /* Now we've got some meaningful data in the database to start querying */ /* One way to find something you’re looking for is by forming a query as follows. * The "FirstOrDefault" should be used when you expect there to be only one entity * with the properties you specify. */ User findMatt = context.Users.FirstOrDefault(user => user.Username == "matt"); Console.WriteLine("Found user: " + findMatt.Username); /* Let's see how we can follow a navigation property. Since ConfirmedEvents * is a navigation property for a many-to-many relationship, it will be * something over which we can iterate in a foreach */ Console.WriteLine("Matt is attending " + findMatt.ConfirmedEvents.Count() + " events, including: "); foreach (Event mattsEvents in findMatt.ConfirmedEvents) { Console.WriteLine(mattsEvents.Title); } /* We can also explore the many-to-many relationship in the other direction. */ Console.WriteLine("Attendees of the bbq:"); foreach (User attendee in bbq.Attendees) { Console.WriteLine(attendee.Username); } /* Pause at the end of execution */ Console.Read(); } } } } /* Output: Users before add: 0 Users before save: 0 Users after save: 1 Found user: matt Matt is attending 1 events, including: Barbeque Attendees of the bbq: matt */

Sign up to vote on this title
UsefulNot useful