Entity Framework CTP 4.0 – Data Fetching

Posted: October 17, 2010 in .NET, ADO.NET Entity Framework, C#
Tags: ,

In the last two posts I have discussed about Entity Framework CTP 4.0 Code First Approach and Database Initialization.Now we will take a look at how to define relationships and navigational properties between the Entities and how data fetching is impacted by these.

We will consider two tables Course and Department as example.

ed

These tables are modeled as the following entity classes.

public class Course
{
    public int CourseID { get; set; }
    public string Title { get; set; }
    public int Credits { get; set; }
    public Department Department { get; set; } 

}
public class Department
{
    public int DepartmentID { get; set; }
    public string Name { get; set; }
    public decimal  Budget { get; set; }
    public DateTime StartDate { get; set; }
    public int Administrator { get; set; }
    public ICollection<Course> Courses { get; set; }
} 

Then the entity configuration and database context classes are defined as shown below:

public class CourseConfig:EntityConfiguration<Course>
  {
      public CourseConfig()
      {
          MapSingleType(
                          a =>
                              new 
                              {
                                  a.CourseID,
                                  a.Title,
                                  a.Credits,
                                  a.Department.DepartmentID
                              }
                       ).ToTable("dbo.Course"); 

          HasKey((a) => a.CourseID); 

          Property(a => a.Title).IsRequired();
      }
  }
  public class DepartmentConfig : EntityConfiguration<Department>
  {
      public DepartmentConfig()
      {
          MapSingleType(
                          a =>
                              new
                              {
                                  a.DepartmentID,
                                  a.Name,
                                  a.StartDate,
                                  a.Administrator,
                                  a.Budget
                              }
                       ).ToTable("dbo.Department"); 

          HasKey((a) => a.DepartmentID);
          Property(a => a.Name).IsRequired();
      }
  } 

public class SchoolDBContext:DbContext
{
    public SchoolDBContext(DbModel model,string name) : base(name,model ) { }
    public DbSet<Course> Courses { get; set; }
    public DbSet<Department> Departments { get; set; } 

    public ObjectContext ObjectContext
    {
        get
        {
            return base.ObjectContext;
        }
    }
}

 

Now let’s try to fetch data into Course and Department object using the following code:

static void Main(string[] args)
    {
        Database.DefaultConnectionFactory = new
            SqlConnectionFactory("Server=SANKARSAN;Database=School;Trusted_Connection=True;MultipleActiveResultSets=True"); 

        ModelBuilder builder = new ModelBuilder();
        builder.Configurations.Add(new CourseConfig());
        builder.Configurations.Add(new DepartmentConfig());
        DbModel model = builder.CreateModel(); 

        using (var context = new SchoolDBContext(model, "school"))
        {
            Database.SetInitializer<SchoolDBContext>(null);
            foreach (var c in context.Courses)
            {
                Console.WriteLine("Course Title: {0}",c.Title);
                Console.WriteLine("Credits: {0}",c.Credits);
                Console.WriteLine("Department : {0}",c.Department.Name);
                Console.WriteLine("----------------------------------");
            }
        }
        Console.Read();
    }
} 

 

The values for Department are not getting populated.

qwatch

So where lies the problem?.By default Lazy Loading is enabled for DbContext.Ideally it should fetch the Department record corresponding to that Course.

This has nothing do with CTP 4.0.In EF 4.0, Lazy Loading of POCO entities needs a proxy class which is dynamically generated at runtime.This class inherits from the entity classes( Course & Department in this case) and overrides the navigational properties to load data.So I need to mark the navigational properties as virtual.I had missed this while creating my entity classes.Once these are marked the program works perfectly fine and loads the data for Department entity lazily.We can see the dynamic proxy using quick watch window:

qwatch1

How to turn off lazy loading and enable eager loading?

DbContext class wraps the System.Data.Objects.ObjectContext class exposes it as a protected property.I have used the same in SchoolDBContext class as ObjectContextProperty.

    public new ObjectContext ObjectContext
    {
        get
        {
            return base.ObjectContext;
        }
    } 

We can turn off lazy loading in the following way:

context.ObjectContext.ContextOptions.LazyLoadingEnabled = false; 

When lazy loading is turned off we can either go for explicit loading using ObjectContext.LoadProperty as shown below:

if (c.Department == null) context.ObjectContext.LoadProperty<Course>(c, x => x.Department); 

To do eager loading we need to use the Include extension methods on System.Linq.IQueryable<T>.In CTP 4.0 a new overload of extension method Include is added which allows us to pass a LINQ expression as shown below:

foreach (var d in context.Departments.Include<Department>(d=>d.Courses))
{
    Console.WriteLine("Name: {0}", d.Name);
    Console.WriteLine("Start Date: {0}", d.Budget);
    foreach (var c in d.Courses)
    {
        Console.WriteLine("Course : {0}", c.Title);
    }
    Console.WriteLine("----------------------------------");
} 
Comments
  1. Entity Framework CTP 4.0 – Data Fetching « Sankarsan’s Journal…

    Thank you for submitting this cool story – Trackback from DotNetShoutout…

  2. […] post: Entity Framework CTP 4.0 – Data Fetching « Sankarsan's Journal No […]

  3. Martin Nyborg says:

    Nice work

    I guess that the next logical steep is many-to-many mapping?

    I am struggling with mapping an existing database where conventions is of no use.

    Hope that U have the time to help

  4. […] my last post I had discussed about entity relationships,navigational properties and how we can fetch data from […]

  5. Cazenave says:

    Hi!
    Very helpful summary about Include method.

    Although, I can not find the Include overload which takes a Linq expression as parameter.

    I have the CTP4 installed.
    Is there any other dll to reference in order to get this overload?

    Thx

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.