Using the Entity Framework: Create Operation (Quick Reference)

How to Use the Entity Framework to Create Records in a Relational Database

This quick reference is for those who are trying out the Entity Framework and want examples of how to perform everyday CRUD tasks. We’ll take a look at how to create objects and manage relationships working with the Entity Framework’s occasionally unclear object model.

Quick Reference Setup

Entity Framework & Linq to Entities: “Movies” Example Setup contains diagrams representing the database structure, entity data model, and entity object model used in the following code examples.

Create a Director object using the Entity Framework

private static MovieEntities _entities = new MovieEntities();

static void Main(string[] args)
{
     Director spikeJonze = Director.CreateDirector(
          0, 
          "Spike Jonze", 
          "Rockville Maryland", 
          "10/22/1969"
     );
     
     // Use the AddToDirectorSet method
     _entities.AddToDirectorSet(spikeJonze);

     // Could have also used the AddObject method
     // _entities.AddObject("MovieEntities.DirectorSet", 
     //     spikeJonze);

     Console.WriteLine("--> Director added to DirectorSet");
     Console.WriteLine("EntityKey is temporary: {0}", 
          spikeJonze.EntityKey.IsTemporary);

     _entities.SaveChanges();

     Console.WriteLine("--> Changes Saved");
     Console.WriteLine("EntityKey is temporary: {0}", 
          spikeJonze.EntityKey.IsTemporary);
     Console.WriteLine("EntityKey Key: {0}, 
          EntityKey Value: {1}", 
          spikeJonze.EntityKey.EntityKeyValues[0].Key,
          spikeJonze.EntityKey.EntityKeyValues[0].Value);

     Console.ReadLine();
}

We use the CreateDirector to initialize a new Director object. Notice that 0 is specified for the ID parameter. Though this argument is required, the value you provide is of no consequence. Once the Director is added to the DirectorSet, a temporary EntityKey is created. The call to SaveChanges adds the Director object’s data values to the database and the primary key resulting from the database insert is retrieved. From that point on the EntityKey’s value will be synchronized with the identity column for the Director record in the database.

There are multiple ways to add an entity object to the ObjectContext. Two of which are illustrated in this example. Which method you choose is a matter of preference.

Here is the output:

--> Director added to DirectorSet
EntityKey is temporary: True
--> Changes Saved
EntityKey is temporary: False
EntityKey Key: ID, EntityKey Value: 27

Create a Director object and an associated Movie object using the Entity Framework

private static MovieEntities _entities = new MovieEntities();

static void Main(string[] args)
{
     Director spikeJonze = new Director { 
          Name = "Adam Spiegel a.k.a., Spike Jonze", 
          Hometown = "Rockville Maryland", 
          Birthday = "10/22/1969" 
     };
     _entities.AddToDirectorSet(spikeJonze);

     Movie wildThings = new Movie { 
          Title = "Where the Wild Things Are", 
          DateReleased = DateTime.Parse("10/1/2009") 
     };
     spikeJonze.Movies.Add(wildThings);

     _entities.SaveChanges();
     Console.ReadLine();
}

We use object initialization syntax to create a Director object and then add it to the ObjectContext’s DirectorSet collection. We then create a Movie object and add it to the Director’s Movies collection. Doing so creates a relationship (with corresponding temporary EntityKeys) between the Director and the Movie. Calling the SaveChanges method updates the database to reflect the changes we’ve made to the entity data model.

There are multiple ways to initialize object in CSharp. When working with the Entity Framework, I prefer to use object initialization syntax (used in this example) in lieu of using the CreateDirector factory method. Though there is a benefit to using the factory method in that you are forced to provide initial values for all properties. What you use is a matter of preference.

Create a Movie object and associate it with an existing Director object using the Entity Framework

private static MovieEntities _entities = new MovieEntities();

static void Main(string[] args)
{
     Director robReiner = _entities.DirectorSet.Where(
               d => d.Name == "Rob Reiner").First();

     Movie thePrincessBride = new Movie {
          Title = "The Princess Bride",
          DateReleased = DateTime.Parse("1/1/1987")
     };

     robReiner.Movies.Add(thePrincessBride);
     _entities.SaveChanges();
     Console.ReadLine();
}

First we load the appropriate Director object. Next we create the Movie object and add it to the Director’s Movies collection. Doing so creates the necessary relationship. Finally, we call the ObjectContext’s SaveChanges() method which inspects the context’s ObjectStateManager and commits any changes that had been made to the model’s entities or associations since it was created or since SaveChanges() was last called.

Create a Movie object and associate it with an existing Director object without loading the Director object using the Entity Framework

private static MovieEntities _entities = new MovieEntities();

static void Main(string[] args)
{
     int robReinerID = 2;
     Movie thePrincessBride = new Movie {
          Title = "The Princess Bride (New)",
          DateReleased = DateTime.Parse("1/1/1987")
     };

     thePrincessBride.DirectorReference.EntityKey = new
          EntityKey("MovieEntities.DirectorSet",
                    "ID", robReinerID);
     _entities.AddToMovieSet(thePrincessBride);
     _entities.SaveChanges();
     Console.ReadLine();
}

Since we know the Director’s ID, there is no need to load the Director object in order to create the Movie. It is necessary, however, to set the EntityKey property of the DirectorReference (an EntityReference type). Note that the first argument passed to the EntityKey’s constructor is an EntitySet within the ObjectContext; e.g., MovieEntities.DirectorSet.

Exploring the Entity Framework’s ObjectStateManager

private static MovieEntities _entities = new MovieEntities();

static void Main(string[] args)
{
     Director robReiner = _entities.DirectorSet.Where(
               d => d.Name == "Rob Reiner").First();

     Movie thePrincessBride = new Movie { 
          Title = "The Princess Bride", 
          DateReleased = DateTime.Parse("1/1/1987") 
     };

     robReiner.Movies.Add(thePrincessBride);
     IEnumerable<ObjectStateEntry> entries = 
          _entities.ObjectStateManager.
          GetObjectStateEntries(EntityState.Added);
				
     foreach (ObjectStateEntry entry in entries)
     {
          Console.WriteLine("Entity Set: {0}", entry.EntitySet);
	  Console.WriteLine("IsRelationship: {0}", 
               entry.IsRelationship);
	  Console.WriteLine("State: {0}", entry.State);
				
	  if (!entry.IsRelationship)
	  {
	     Console.WriteLine("EntityKey is null: {0}", 
                  entry.EntityKey.EntityKeyValues == null);
             Console.WriteLine("EntityKey is temporary: {0}", 
                  entry.EntityKey.IsTemporary);
	  }

          entry.AcceptChanges();
          Console.WriteLine("--> Changes Accepted");

	  if (!entry.IsRelationship)
	  {
	        Console.WriteLine("EntityKey is: {0}", 
                     entry.EntityKey.EntityKeyValues.First());
		Console.WriteLine("EntityKey is temporary: {0}", 
                     entry.EntityKey.IsTemporary);
	  }

          Console.WriteLine("State: {0}\n\n", entry.State);
     }

     // The following call to SaveChanges() does nothing
     // because calling AcceptChanges() on each entry updated
     // their respective states from "Added" to "Unchanged".
     _entities.SaveChanges(); 

     Console.ReadLine();
}

First we add a Movie to a Director’s collection of Movies. Doing so adds two ObjectStateEntries to the ObjectStateManager. ObjectStateEntries are used to track changes made to the entity model. One of the entries is for the Movie entity that was added and the second is for the relationship that was created between the Movie and the Director. We then grab the ObjectStateEntries where the EntityState equals “Added”. Looping over the ObjectStateEntries allows us to see various properties of the entries before and after AcceptChanges is called. When AcceptChanges is called on a given entry, its state is set to “Unchanged”. Therefore, the subsequent call to SaveChanges does nothing since the state of all ObjectStateEntries is “Unchanged” at the time SaveChanges is called. Retrieving a list of Movies would reveal that the Movie was not inserted into the database.

Here is the output:

Entity Set: FK_Movies_Directors
IsRelationship: True
State: Added
--> Changes Accepted
State: Unchanged


Entity Set: MovieSet
IsRelationship: False
State: Added
EntityKey is null: True
EntityKey is temporary: True
--> Changes Accepted
EntityKey is: [ID, 0]
EntityKey is temporary: False
State: Unchanged
Advertisements

One Response

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: