(Follow Up) Best practice and effective use of DataContext in LINQ

NOTE: 3/24/2008 - The problem of working with LINQ to sql extends beyond lifetime management of DataContext, thus I am scrapping the second part of my blog. Only thing useful in this post is the performance comparision. Here's new post on LINQ to SQL

In my previous post, I had probed a question on how to effectively incorporate DataContext in ones pattern so the ease of use and unit of work is well represented. Thanks to everyone who provided feedback, it definitely was a good read and provided lots of insight. Few reasons we got into asking this question instead of using simple create/dispose model, in the first place was

  • We wanted to make it so that it was easy to use
  • We heavily use Repository Pattern for business logic/transaction scoping and Entity model for CRUD operations, so wanted to make sure datacontext we used was as efficient as possible.
  • Concerns regarding efficiency of creating/disposing datacontext and not being able to use caching of datacontext effectively.

 

However, after reading several posts and looking deeper into datacontext, it seems that creating/disposing it as required is the best way to go. In order, to get rid of any suspicion I even created a little test to compare Ambient Context and Instantiation as required model, results are below. In the image below, first method GetByID(int32) actually instantiates datacontext everytime, where as the second one takes in a datacontext instantiated once by the caller (code is included at the bottom of the post). The results are impressive for dynamic instantiation. 23.7 secs vs. 20.9 secs for 6200 iterations. I think 3 secs is a reasonable margin not taking into account impact in memory with ambient datacontext or the efficiency of caching.

 

 

Either way, I believe for our purpose and in general a repository pattern incorporated with entity model should work pretty well. One thing Jeff did point out to me however was, once you have disposed your datacontext, any attempt to load/access child objects that is marked for lazy load will throw disposed object error as below. So make sure you load your objects while the context is alive, once that is done subsequent access is successful.

 

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
using System.Diagnostics;

namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {
//Create & dispose Context everytime
            Test1();
            
        //Ambient Context Concept
Test2();
        }

//Create datacontext everytime
        private static void Test1()
        {
            List<EcardOrder> orders;
            using (MercyDataContext dbContext = new MercyDataContext())
            {
                for (int i = 0; i < 100; i++)
                {
                    orders = dbContext.EcardOrders.ToList();
                    foreach (EcardOrder order in orders)
                    {
                        //Datacontext will be created everytime 
// in this function
                        Ecard card = Ecard.GetByID(order.EcardID);
                    }
                }
            }
        }

        
//Create datacontext only once
        private static void Test2()
        {
            List<EcardOrder> orders;
            using (MercyDataContext dbContext = new MercyDataContext())
            {
                for (int i = 0; i < 100; i++)
                {
                    orders = dbContext.EcardOrders.ToList();
                    foreach (EcardOrder order in orders)
                    {
                        //Pass datacontext to the function as well
                        Ecard card = Ecard.GetByID(order.EcardID, dbContext);
                    }
                }
            }
        }


    }

    /// <summary>
    /// Partial Ecard class extended from database
    /// </summary>
    public partial class Ecard
    {
        //new datacontext is created and disposed everytime.
        public static Ecard GetByID(int ID)
        {
            using (MercyDataContext _context = new MercyDataContext())
            {
                return _context.Ecards.SingleOrDefault(e => e.EcardID == ID);
            }
        }

        //Puesdo concept of ambient datacontext
        //NOTE: once the Ecard is loaded it is cached in the context, 
        //thus items will be returned from cache
        public static Ecard GetByID(int ID, MercyDataContext _context)
        {
            return _context.Ecards.SingleOrDefault(e => e.EcardID == ID);
        }
    }


}

Print | posted on Thursday, March 20, 2008 4:46 PM

Feedback

# re: (Follow Up) Best practice and effective use of DataContext in LINQ

Left by Mohammad Azam at 3/31/2008 4:31 PM
Gravatar Hi,

This is a reasonable approach kinda repeatable but I guess okay.

Your comment:





 
Please add 1 and 2 and type the answer here:

Copyright © Bigyan Rajbhandari