<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>LINQ</title>
        <link>http://www.dotnetlog.com/category/13.aspx</link>
        <description>LINQ</description>
        <language>en-US</language>
        <copyright>Bigyan Rajbhandari</copyright>
        <managingEditor>bigyanr@gmail.com</managingEditor>
        <generator>Subtext Version 1.9.5.177</generator>
        <item>
            <title>Is V1 of LINQ to SQL only suitable for RAD?</title>
            <link>http://dotnetlog.com/archive/2008/03/24/is-v1-of-linq-to-sql-only-suitable-for-rad.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://dotnetlog.com/archive/2008/03/20/follow-up--best-practice-and-effective-use-of-datacontext.aspx"&gt;In my previous couple posts&lt;/a&gt;, I have been religiously trying to solve the problem or should I say 'find a best pattern' to use with linq to sql. In past few projects, I ventured into Linq to sql world abandoning ORM tools (OR mapper, NHibernate…) that I had been using; however, I have been greatly disappointed by the fact that Linq to sql doesn't support few fundamental concepts/patterns (LINQ to SQL takes a little different approach than traditional ORM tools). I am starting to have serious doubts if V1 of Linq2SQl is even cut out for any n-tier application (I am not even thinking enterprise application). Don't get me wrong, LINQ is a great framework and LINQ to SQL is an awesome extension. But in the real world business application the implementation of LINQ to SQL out of the box is not practical. How did I arrive to this conclusion? Here's how: &lt;/p&gt;
&lt;p&gt;The two fundamental problems it fails to support out of the box are: &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1.&lt;/strong&gt; Working with objects in LINQ to SQL in disconnected context is painful. i.e. Most mid-large size applications are designed as n-tier architecture, thus entities within LINQ act more as a container (DTO or Business objects) for carrying data from one tier to another. The problem with LINQ to SQL is that disconnecting from one datacontext and reattaching to another is not trivial. This is a serious drawback given the fact that almost all the applications needs to use this model other than "quick demos". &lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
I have seen lots of posts/articles from developers questioning the same problem. Various people have taken a stab at solving this, if you are seriously considering LINQ to SQL read these. &lt;/p&gt;
&lt;ul style="MARGIN-LEFT: 54pt"&gt;
    &lt;li&gt;&lt;a href="http://pampanotes.tercerplaneta.com/2008/03/implementing-n-tier-change-tracking.html"&gt;Benjamin's&lt;/a&gt; ULinqGen project in codeplex allows change tracking in pure POCO models &lt;/li&gt;
    &lt;li&gt;Post by &lt;a href="http://www.west-wind.com/WebLog/posts/134095.aspx"&gt;Rick Strahl&lt;/a&gt;, explaining problem in Linq to SQL in a disconnected environment. &lt;/li&gt;
    &lt;li&gt;
    &lt;div&gt;&lt;a href="http://www.codeplex.com/LINQ2SQLEB"&gt;Matt's Linq2SqlEB&lt;/a&gt; project in codeplex which implements synchronization. &lt;/div&gt;
    &lt;p style="MARGIN-LEFT: 18pt"&gt; &lt;/p&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;2. &lt;/strong&gt;If you somehow implement an architecture to have live datacontext, one serious issue that you need to focus on is the lifetime management of DataContext. Please be aware, that poorly managed datacontext will bloat eventually and will hamper performance. &lt;/p&gt;
&lt;ul style="MARGIN-LEFT: 54pt"&gt;
    &lt;li&gt;&lt;a href="http://www.dotnetlog.com/archive/2008/03/18/best-practice-and-effective-way-of-using-datacontext-in-linq.aspxhttp:/www.dotnetlog.com/archive/2008/03/18/best-practice-and-effective-way-of-using-datacontext-in-linq.aspx"&gt;See my previous post&lt;/a&gt; on managing lifetime of datacontext &lt;/li&gt;
    &lt;li&gt;Rick Strahl discusses datacontext lifetime management &lt;a href="http://www.west-wind.net/WebLog/posts/246222.aspx"&gt;here&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://weblogs.asp.net/despos/archive/2008/03/19/more-on-datacontext-in-hopefully-a-realistic-world.aspx"&gt;Dino Esposito&lt;/a&gt;, suggest that you should use atomic context, but I don't see how it would solve the problem if you can't work in a disconnected environment. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;&lt;br /&gt;
Am I ready to make jump to LinqToSql in my next project from my previous ORM tools? I don't know about others but, I will be holding back until I figure out a best way to work in a disconnected environment, which might be the next project. But the point is disconnected context support will be required. &lt;a href="http://blogs.msdn.com/dinesh.kulkarni/"&gt;Dinesh Kulkarni&lt;/a&gt;, a senior dev for Linq to SQL team advises not use Active Record Pattern, but the problem is I don't see any pattern that I can use effectively in a n-tier architecture, not only the Active Record. LINQ to SQL itself uses great patterns within, but the way datacontext is managed and Entities/child entities are persisted it presents a different problem. It makes for a great presentation or RAD applications so far, but fails to support n-tier applications easily. I am considering concepts of offline datacontext and will follow up with more posts on this. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is ADO.Net Entity Framework an answer?&lt;br /&gt;
&lt;/strong&gt;Not really. The framework uses same concept of active context as Linq to SQL and quickly runs into the problem in a disconnected environment. I haven't done an in-depth implementation of it but the problem seems to be the same. &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Let me know what you guys think of LINQ to SQL. &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;&lt;img src="http://dotnetlog.com/aggbug/56.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Bigyan Rajbhandari</dc:creator>
            <guid>http://dotnetlog.com/archive/2008/03/24/is-v1-of-linq-to-sql-only-suitable-for-rad.aspx</guid>
            <pubDate>Tue, 25 Mar 2008 03:31:38 GMT</pubDate>
            <wfw:comment>http://dotnetlog.com/comments/56.aspx</wfw:comment>
            <comments>http://dotnetlog.com/archive/2008/03/24/is-v1-of-linq-to-sql-only-suitable-for-rad.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://dotnetlog.com/comments/commentRss/56.aspx</wfw:commentRss>
        </item>
        <item>
            <title>(Follow Up)  Best practice and effective use of DataContext in LINQ</title>
            <link>http://dotnetlog.com/archive/2008/03/20/follow-up--best-practice-and-effective-use-of-datacontext.aspx</link>
            <description>&lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;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. &lt;a href="http://www.dotnetlog.com/archive/2008/03/24/is-v1-of-linq-to-sql-only-suitable-for-rad.aspx"&gt;Here's new post on LINQ to SQL&lt;/a&gt;&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.dotnetlog.com/archive/2008/03/18/best-practice-and-effective-way-of-using-datacontext-in-linq.aspx"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;In my previous post&lt;/span&gt;&lt;/a&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; BACKGROUND-COLOR: white"&gt;, 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 &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; BACKGROUND-COLOR: white"&gt;We wanted to make it so that it was easy to use &lt;/span&gt;&lt;/li&gt;
    &lt;li&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; BACKGROUND-COLOR: white"&gt;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. &lt;/span&gt;&lt;/li&gt;
    &lt;li&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; BACKGROUND-COLOR: white"&gt;Concerns regarding efficiency of creating/disposing datacontext and not being able to use caching of datacontext effectively. &lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; BACKGROUND-COLOR: white"&gt;&lt;strike&gt;However, after reading several posts and looking deeper into datacontext, it seems that creating/disposing it as required is the best way to go&lt;/strike&gt;. 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. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://dotnetlog.com/images/dotnetlog_com/032008_2146_FollowUpBe1.png" /&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; BACKGROUND-COLOR: white"&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; BACKGROUND-COLOR: white"&gt;&lt;strike&gt;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. &lt;/strike&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://dotnetlog.com/images/dotnetlog_com/032008_2146_FollowUpBe2.png" /&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; BACKGROUND-COLOR: white"&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Text;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Timers;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Diagnostics;

&lt;span class="kwrd"&gt;namespace&lt;/span&gt; ConsoleApplication4
{
    &lt;span class="kwrd"&gt;class&lt;/span&gt; Program
    {
        &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)
        {
&lt;span class="rem"&gt;//Create &amp;amp; dispose Context everytime&lt;/span&gt;
            Test1();
            
        &lt;span class="rem"&gt;//Ambient Context Concept&lt;/span&gt;
Test2();
        }

&lt;span class="rem"&gt;//Create datacontext everytime&lt;/span&gt;
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Test1()
        {
            List&amp;lt;EcardOrder&amp;gt; orders;
            &lt;span class="kwrd"&gt;using&lt;/span&gt; (MercyDataContext dbContext = &lt;span class="kwrd"&gt;new&lt;/span&gt; MercyDataContext())
            {
                &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 100; i++)
                {
                    orders = dbContext.EcardOrders.ToList();
                    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (EcardOrder order &lt;span class="kwrd"&gt;in&lt;/span&gt; orders)
                    {
                        &lt;span class="rem"&gt;//Datacontext will be created everytime &lt;/span&gt;
&lt;span class="rem"&gt;// in this function&lt;/span&gt;
                        Ecard card = Ecard.GetByID(order.EcardID);
                    }
                }
            }
        }

        
&lt;span class="rem"&gt;//Create datacontext only once&lt;/span&gt;
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Test2()
        {
            List&amp;lt;EcardOrder&amp;gt; orders;
            &lt;span class="kwrd"&gt;using&lt;/span&gt; (MercyDataContext dbContext = &lt;span class="kwrd"&gt;new&lt;/span&gt; MercyDataContext())
            {
                &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 100; i++)
                {
                    orders = dbContext.EcardOrders.ToList();
                    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (EcardOrder order &lt;span class="kwrd"&gt;in&lt;/span&gt; orders)
                    {
                        &lt;span class="rem"&gt;//Pass datacontext to the function as well&lt;/span&gt;
                        Ecard card = Ecard.GetByID(order.EcardID, dbContext);
                    }
                }
            }
        }


    }

    &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;/// Partial Ecard class extended from database&lt;/span&gt;
    &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Ecard
    {
        &lt;span class="rem"&gt;//new datacontext is created and disposed everytime.&lt;/span&gt;
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Ecard GetByID(&lt;span class="kwrd"&gt;int&lt;/span&gt; ID)
        {
            &lt;span class="kwrd"&gt;using&lt;/span&gt; (MercyDataContext _context = &lt;span class="kwrd"&gt;new&lt;/span&gt; MercyDataContext())
            {
                &lt;span class="kwrd"&gt;return&lt;/span&gt; _context.Ecards.SingleOrDefault(e =&amp;gt; e.EcardID == ID);
            }
        }

        &lt;span class="rem"&gt;//Puesdo concept of ambient datacontext&lt;/span&gt;
        &lt;span class="rem"&gt;//NOTE: once the Ecard is loaded it is cached in the context, &lt;/span&gt;
        &lt;span class="rem"&gt;//thus items will be returned from cache&lt;/span&gt;
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Ecard GetByID(&lt;span class="kwrd"&gt;int&lt;/span&gt; ID, MercyDataContext _context)
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt; _context.Ecards.SingleOrDefault(e =&amp;gt; e.EcardID == ID);
        }
    }


}
&lt;/pre&gt;&lt;img src="http://dotnetlog.com/aggbug/55.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Bigyan Rajbhandari</dc:creator>
            <guid>http://dotnetlog.com/archive/2008/03/20/follow-up--best-practice-and-effective-use-of-datacontext.aspx</guid>
            <pubDate>Thu, 20 Mar 2008 21:46:24 GMT</pubDate>
            <wfw:comment>http://dotnetlog.com/comments/55.aspx</wfw:comment>
            <comments>http://dotnetlog.com/archive/2008/03/20/follow-up--best-practice-and-effective-use-of-datacontext.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://dotnetlog.com/comments/commentRss/55.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>