Tuesday, March 29, 2011

Entity Framework 4.1 Entry Extensions

I have been working with the Microsoft Entity Framework version 4.1 aka "Code First" for about the last 3 weeks and have been really enjoying the ease and flexibility of setting things up and getting my CRUD operation working so smoothly. However, I had the need to create modify some entities in my database and was starting down the path of passing in the new entity, then querying the context for the old entity and finally setting the values of the old entity to those of the new entity. This worked for a little while, when I only had simple entities. However, my entities started getting more complex and I found myself adding more properties and always forgetting to update the modify operation.

using System.ComponentModel.DataSetAnnotations;
public class Person
{
[Key]
public int ID { get; set; }
[StringLength(100)]
public string FirstName { get; set; }
[StringLength(100)]
public string LastName { get; set; }
}
view raw Entity.cs hosted with ❤ by GitHub


using System.Data.Entity;
public class Program
{
public static void Main(string[] args)
{
var modifiedPerson = new Person
{
ID = 1,
FirstName = "John",
LastName = "Doe"
};
var context = new EntityContext();
var originalPerson = context.People.Find(1);
originalPerson.FirstName = modifiedPerson.FirstName;
originalPerson.LastName = modifiedPerson.LastName;
context.People.Attach(originalPerson);
context.SaveChanges();
}
}
view raw ModifyEntity.cs hosted with ❤ by GitHub


So I started doing some research and found that I could use the Attach method on the DbSet to add the modified entity. However, this left the entity in the UnChanged state and that did not really do me any good. So with a little more research I found this Blog Post by Julie Lerman about Round Tripping a Timestamp Field in EF 4.1 with MVC 3 that discusses the DbContext.Entry method and how I can set the State as I attach the entity.

public class Program
{
public static void Main(string[] args)
{
var person = GetModifiedPersonMethod();
var context = new EntityContext();
context.Entry(person).State = EntityState.Modified;
context.SaveChanges();
}
}
view raw EntryState.cs hosted with ❤ by GitHub


I had also in my secondary research found this post about creating extensions for the ObjectContext in the regular Entity Framework and this led to the creation of my own Extensions for the DbContext object as seen below...

public static DbContextExtensions
{
public static void EntryAsModified<T>(this DbContext context, T entity) where T : class
{
context.Entry(entity).State = EntityState.Modified;
}
public static void EntriesAsModified<T>(this DbContext context, IEnumerable<T> entities) where T : class
{
foreach(var entity in entities)
{
context.Entry(entity).State = EntityState.Modified;
}
}
}


I now use these extension methods as shown below.

public class Program
{
public static void Main(string[] args)
{
var person = GetModifiedPersonMethod();
var context = new EntityContext();
context.EntryAsModified(person);
context.SaveChanges();
var people = GetModifiedPeopleMethod();
context.EntriesAsModified(people);
context.SaveChanges();
}
}

No comments: