Nov 16, 2013

Update Mvc application from 4 to 5

Make sure you have back up of your project before you start updating your project.

Open Manage Nuget Package for the solution
Update Entity Framework
Update Asp.Net Mvc
Update Asp.Net Mvc web api2
Installed Microsoft.AspNet.WebHelpers

The idea is to update only top level package and it automatically updated other packages on which these packages were dependent on.

Update web.config
<add key="webpages:Version" value="3.0.0.0" />

And Update web.config in views folder for mvc version to 5

Compile your project and you should be ready to go at least I was able to update my project following these steps.

Nov 8, 2013

Deferred vs Eager loading in Entity Framework

In lazy loading related data isn't retrieved when entity is first read. These are automatically retrieved the first time when you attempt to access it.

 IEnumerable products = productContext.Products; 
 
 foreach (var p in products.ToList()) //Query tblProduct
 {
    var reviews = p.Reviews; //Query tblReview related to Product p, which will mean this query will be executed for each products
 }


Explicit loading is similar to Lazy loading except that related data retrieve doesn't happen automatically

 productContext.Configuration.LazyLoadingEnabled = false;
 IEnumerable products = productContext.Products;
 
 foreach (var product in products.ToList()) //Query tblProduct
 {
  productContext.Entry(product).Collection(x=>x.Reviews).Load(); //Query tblReview related to Product p
  productContainer.Entry(product).Collection(x=>x.Reviews).Query().Where(r=>r.Name.FirstName=="test").Load();
  var reviews = p.Reviews;  
 }

These are also known as deferred loading. Deferred loading can be used for cases where you have complex join or you are going to use related data only for subset of entity. Like you retrieve all product (may be 1000 in number) and display review only for the first product. For lazing loading you have to make sure that the ObjectContext instance has not been disposed, otherwise you will get exception, so the following will not work

 using (var productContainer = new ProductContainerCodeFirst())
 {
  products = productContainer.Products.ToList();
 }
 
//The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
 foreach (var review in product.Reviews)

In Eager loading related data is retrieved when entity is read. This result in single join query that retrieve all the related data. This can be achieved by setting LazyLoadingEnabled = false or by removing virtual keyword when you declare the property.

 productContext.Configuration.LazyLoadingEnabled = false;
 products = productContainer.Products.Include(a => a.Reviews.Select(b => b.Address)).Include(a => a.Reviews.Select(b => b.Name)).ToList();
 
 foreach (var p in products) //Query tblProduct and tblReview
 {
    var reviews = p.Reviews; 
 }

In general, if you know you need related data for every entity retrieved, eager loading offers the best performance, because a single query sent to the database is typically more efficient than separate queries for each entity retrieved. Also during serialization, you would want to turn lazy loading off as a serialize accesses all properties which will mean it will trigger a query for each navigation property that it accesses The DbContext class performs lazy loading by default. To disable remove virtual keyword when you declare the property or set LazyLoadingEnabled to false.

Referenced POCO

    [Table("tblProduct")]
    public class Product
    {
  public string Name { get; set; }
        public  virtual List Reviews { get; set; }
    }

    
    [Table("tblReview")]
    public class Review
    {
        public int Id { get; set; }
        public string ReviewerName { get; set; }
        public virtual Name Name { get; set; }
    }

   [Table("tblName")]
    public class Name
    {
        public int Id { get; set; }
        public string LastName { get; set; }
        public string FirstName { get; set; }
    }