<?xml version="1.0"?><?xml-stylesheet type="text/xsl" href="http://www.codeplex.com/rss.xsl"?><rss version="2.0"><channel><title>MultiTierLinqToSql Wiki &amp; Documentation Rss Feed</title><link>http://www.codeplex.com/MultiTierLinqToSql/Wiki/View.aspx?title=Home</link><description>MultiTierLinqToSql Wiki Rss Description</description><item><title>Updated Wiki: Home</title><link>http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=Home&amp;version=21</link><description>&lt;div class="wikidoc"&gt;&lt;h1&gt;Multi tier architecture for Linq to Sql&lt;/h1&gt;

&lt;h2&gt;Introduction&lt;/h2&gt;
This resource shows an approach for using Linq to Sql within a multi tier Asp.Net application, and particularly how it can be made to work well with ObjectDataSources. It is here as a discussion piece as well as a usable bit of code.&lt;br /&gt;&lt;br /&gt;The key features are a Request-scoped datacontext and entity repository classes which provide easy to use Create, Retrieve, Update and Delete (CRUD) operations implemented with Generics. Also included is a T4 template for auto generation of repositories from a dbml file. &lt;br /&gt;&lt;br /&gt;See here for a quick start &lt;a href="http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=code%20overview"&gt;introduction to using the code&lt;/a&gt;
&lt;h2&gt;Generic Entity Repository &lt;/h2&gt;
Each database entity has an associated repository class which is used to perform common CRUD operations. Specific entity repositorys inherit from a generic class &lt;i&gt;GenericRepository&lt;/i&gt; which already implements all the basic Select, Insert, Update &amp;amp; Delete operations.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
[System.ComponentModel.DataObject]
public class GenericRepository&amp;lt;TEntity, TDataContext&amp;gt; where TDataContext : DataContext
{
    public static List&amp;lt;TEntity&amp;gt; SelectAll()
    {
          ...
    }
    public static void Insert(TEntity entity)
    {
        ...
    }
    public static void Update(TEntity entity)
    {
        ...
    }
    public static void Delete(TEntity entity)
    {
        ...
    }
}
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Specific repositories then inherit from this by specifying the entity type which they are concerned with as well as the type of the DataContext used, as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;//ProductRepository class
public class ProductRepository : GenericRepository&amp;lt;Product, NorthwindDataContext&amp;gt;
{
}
&lt;/pre&gt;&lt;br /&gt;which allows client code such as the following:&lt;br /&gt;&lt;pre&gt;
   var productRepository = new ProductRepository();
   IList&amp;lt;Product&amp;gt; products = productRepository.SelectAll();
&lt;/pre&gt;&lt;br /&gt;The use of Generics means that I don't need to add any code at all into my ProductRepository to get all the standard CRUD operations in a fully type safe way. My ProductRepository class can now be customised to add any further data access methods which are specific to Products, for instance GetByCategoryId().&lt;br /&gt;There is also a class GenericStaticRepository which allows you to use this functionality in a static way so in the example above, rather than instantiating a ProductRepository I could simply do this:&lt;br /&gt;&lt;pre&gt;
   IList&amp;lt;Product&amp;gt; products = ProductStaticRepository.SelectAll();
&lt;/pre&gt;&lt;br /&gt;All of these concrete classes are auto generated by the T4 template included with the project as described below.&lt;br /&gt;
&lt;h2&gt;T4 Template&lt;/h2&gt;
Included in the source code is a &lt;a href="http://www.google.co.uk/search?hl=en&amp;amp;q=t4+templates&amp;amp;btnG=Google+Search&amp;amp;meta=&amp;amp;aq=0&amp;amp;oq=t4+tem" class="externalLink"&gt;T4 template&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; which will generate entities and concrete repositories (both static and non-static) with interfaces to facilitate testing. To use it you need to do the following:
&lt;ul&gt;&lt;li&gt;copy the files DataClasses.tt and L2ST4.ttinclude from the T4Templates directory into your project specific datalayer project&lt;/li&gt;
&lt;li&gt;ensure that DataClasses.tt has the same name as the dbml file (so in the example Northwind project DataClasses.tt has been renamed to Northwind.tt to match Northwind.dbml)&lt;/li&gt;
&lt;li&gt;delete the Custom Tool setting for your dbml file in the properties tab - by default it is MSLinqToSQLGenerator which is how your LinqToSql classes get built, but as we are now doing this through a T4 template it is no longer needed and in fact will cause compile errors as there will be multiple definitions of entities.&lt;/li&gt;
&lt;li&gt;to generate the classes, open DataClasses.tt (or whatever it is now called) and save it. You will probably get a dialog box asking if you are sure you  want to do this, click Ok. All the classes will then be generated in a file called &lt;i&gt;DataClasses.generated.cs&lt;/i&gt; where &lt;i&gt;DataClasses&lt;/i&gt; is the same as the name of your dbml file.&lt;/li&gt;&lt;/ul&gt;

&lt;h2&gt;Request scoped DataContext&lt;/h2&gt;
The second part of this solution is the request scoped DataContext. This is a pattern that is commonly used with the Hibernate OR mapper as well as elsewhere, and it means that there is only ever one DataContext per Http request which is stored in the HttpContext.Items collection. It is implemented as a protected property of the GenericRepository class as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
        protected static TDataContext DataContext
        {
            get
            {
                //We are in a web app, use a request scope
                if (HttpContext.Current != null)
                {
                    TDataContext dataContext = (TDataContext)HttpContext.Current.Items[DataContextKey];
                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        HttpContext.Current.Items.Add(DataContextKey, dataContext);
                    }
                    return dataContext;
                }
                else
                {

                    // Creates a Thread Scoped DataContext object that can be reused. 
                    // The DataContext is stored in Thread local storage.
                    // See here http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=361
                    //for a discussion of this code.

                    LocalDataStoreSlot threadData = Thread.GetNamedDataSlot(DataContextKey);
                    object dataContext = null;

                    if (threadData != null)
                        dataContext = Thread.GetData(threadData);

                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        if(threadData == null)
                            threadData = Thread.AllocateNamedDataSlot(DataContextKey);

                        Thread.SetData(threadData, dataContext);
                    }
                    return (TDataContext) dataContext;
                }

            }
        }
&lt;/pre&gt;&lt;br /&gt;As you can see from the code above it handles being used outside a web app by storing the DataContext in a named data slot on the thread it is running in.&lt;br /&gt;&lt;br /&gt;The usefulness of this approach can be seen if you consider a page which uses a number of ObjectDataSources; if we configure our ObjectDataSource to use the DataContext directly then each one will create and dispose of a new DataContext this will not only quickly become a performance overhead, but will also present us with a problem when specifying LoadOptions for the DataContext resulting in more complex, less maintainable code or quite possibly code which doesn't specify loading options at all.&lt;br /&gt;&lt;br /&gt;It should be noted that this approach means that if I have a CategoryRepository class as well as a ProductRepository class, both of which inherit from GenericRepository, both of these classes will use the same DataContext. In other words the DataContext is shared across the whole request, not just by one class type.&lt;br /&gt;
&lt;h2&gt;Custom ObjectDataSource&lt;/h2&gt;
In order for updates to work correctly with databinding it is advisable to use the GenericObjectDataSource control which is included in the DataLayer project. An ordinary ObjectDataSource control will create a new object before doing updates and if there are any unbound properties on this object, they will be left with their default values which will then be saved to the database, the GenericObjectDataSource control gets round this by retrieving the original values from the database, before updating them. For more discussions of the details behind this, see &lt;a href="https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488" class="externalLink"&gt;https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;Submitting changes&lt;/h2&gt;
Another feature of the Linq to Sql architecture is the way that changes are only submitted to the database when the SubmitChanges() method is called on the DataContext. This means that we must either decide at which point to call SubmitChanges() or delegate this responsibility to client code.&lt;br /&gt;To make the classes as flexible as possible any operations which require a call to SubmitChanges (Insert, Update and Delete), are provided with a boolean parameter which specify whether to submit changes immediately or not. There is also an overload of these methods without this parameter which is equivalent to passing true (again this makes use of ObjectDatasources much more straightforward).&lt;br /&gt;The SubmitChanges method of the DataContext is also exposed through the repository class to give Client code the ability to call this explicitly.&lt;br /&gt;
&lt;h2&gt;Sorting and Paging with GridViews&lt;/h2&gt;
There are a number of methods on the GenericRepository class to automatically support paging and sorting in GridViews.&lt;br /&gt;These are:&lt;br /&gt;&lt;pre&gt;
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(int maximumRows, int startRowIndex)
        {
            ...
        }
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression)
        {
         ...
        }
     
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression, int maximumRows, int startRowIndex)
        {
            ...
        }
        public static int Count()
        {
            ...
        }
&lt;/pre&gt;&lt;br /&gt;To use this functionality all you need to do is turn it on in the ObjectDataSource and GridView with the following attributes:&lt;br /&gt;ObjectDataSource: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
EnablePaging=&amp;quot;true&amp;quot; SelectCountMethod=&amp;quot;Count&amp;quot; SortParameterName=&amp;quot;sortExpression&amp;quot;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Gridview:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
AllowPaging=&amp;quot;true&amp;quot; AllowSorting=&amp;quot;true&amp;quot;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And hey presto it just works! This makes it really easy to create sortable, pagable GridViews with no extra coding.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;This release also includes some code from Scott Gu's blog to support Dynamic Querying, see &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx" class="externalLink"&gt;http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; for more details&lt;/i&gt;&lt;br /&gt;
&lt;h2&gt;Logging&lt;/h2&gt;
The code includes an easy way to configure Linq to Sql's logging feature (DataContext.Log) to write to either a text file or the System.Diagnostics.Debugger class which then appears in the output window within Visual Studio.&lt;br /&gt;&lt;br /&gt;To use this functionality you need to add the following lines into your web.config:&lt;br /&gt;&lt;br /&gt;In the &amp;lt;configSections&amp;gt; element:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
&amp;lt;section name=&amp;quot;GenericDataSection&amp;quot; type=&amp;quot;DataLayer.GenericDataSection, DataLayer&amp;quot; allowDefinition=&amp;quot;MachineToApplication&amp;quot; restartOnExternalChanges=&amp;quot;true&amp;quot; requirePermission=&amp;quot;false&amp;quot;/&amp;gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then directly after &amp;lt;configSections&amp;gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
&amp;lt;GenericDataSection LogType=&amp;quot;file&amp;quot; LogFile=&amp;quot;C:\Projects\MultiTierLinqToSql_release\test.txt&amp;quot; DeleteExistingFile=&amp;quot;true&amp;quot;/&amp;gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The first of these lines just declares the second line which is the one that contains the interesting stuff.&lt;br /&gt;There are 3 config options in this section:
&lt;ol&gt;&lt;li&gt;LogType - this can be either 'file' (logs output to a file), 'debug' (logs output to Systems.Diagnostics.Debug) or 'none' (switches logging off). &lt;/li&gt;
&lt;li&gt;LogFile - only applies when LogType is set to 'file', and the default is 'log.txt' it specifies the name of the file to use for logging.&lt;/li&gt;
&lt;li&gt;DeleteExistingFile - only applies when LogType is set to 'file', values can be 'true' or 'false', and the default is true. When this is set to true the file will be overwritten every time a new DataContext is created, effectively once per request. If set to false then all output is appended to the end of the file. This can result in a very large log files so be careful.&lt;/li&gt;&lt;/ol&gt;
&lt;h4&gt;Notes&lt;/h4&gt;
As with all file logging this can be pretty detrimental to performance and so should not be left on in production.&lt;br /&gt;&lt;br /&gt;To handle the logging to the output window I have used the DebuggerWriter class described here: &lt;a href="http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11" class="externalLink"&gt;http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;Error Handling&lt;/h2&gt;
Best practice for managing business rules relating to data integrity with Linq to Sql is to include these rules in partial methods in the entity classes and throw exceptions when they are violated (see http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx for more details).&lt;br /&gt;When using this strategy with an ObjectDataSource, you can then catch these exceptions in the OnUpdated or OnInserted events of your ObjectDataSource and present the information to the user. &lt;br /&gt;To do so you set the OnUpdated and/or the OnInserted attribute of your GenericObjectDatasource:&lt;br /&gt;&lt;pre&gt;
OnUpdated=&amp;quot;ProductDataSource_Updated&amp;quot;
OnInserted=&amp;quot;ProductDataSource_Updated&amp;quot;
&lt;/pre&gt;&lt;br /&gt;and then handle this event in your code behind:&lt;br /&gt;&lt;pre&gt;
protected void ProductDataSource_Updated(object sender, ObjectDataSourceStatusEventArgs e)
    {
        if (e.Exception != null)
        {
            //litError is a literal control which I want to use to display the error to the user
            litError.Text = e.Exception.Message;
            //This tells the objectDataSource that I have handled the error and not to throw it
            e.ExceptionHandled = true;
        }
    }
&lt;/pre&gt;&lt;br /&gt;There is an example of this in the Default.aspx page in the test website.&lt;br /&gt;
&lt;h2&gt;DataLoadOptions&lt;/h2&gt;
As has been widely noted, the way that Linq to Sql works, means that the DataLoadOptions for your DataContext need to be set &lt;i&gt;before&lt;/i&gt; any operations are carried out, and cannot subsequently be changed. This means that in my Asp.Net application I will need to set the DataLoadOptions for the whole request somewhere near the start (assuming of course that I need to set DataLoadOptions at all). It also means that my UI or business layer will need to take responsibility for this. &lt;br /&gt;&lt;br /&gt;What this means in practice is that in a classic Web forms type app I will probably set the DataLoadOptions in the OnInit event of my page, if I'm using MVC then my controller will do it. &lt;br /&gt;
&lt;h2&gt;The code&lt;/h2&gt;
The code consists of 4 projects; GenericDataLayer, which contains the reusable code and 3 demo/test projects
&lt;h3&gt;GenericDataLayer&lt;/h3&gt;
This project contains all of the code you need to use this solution, it can be compiled and referenced in your projects or run as a project within your solutions.&lt;br /&gt;It is made up of:
&lt;ul&gt;&lt;li&gt;GenericRepository class - the main class which implements the generic CRUD methods as discussed above&lt;/li&gt;
&lt;li&gt;GenericObjectDataSource - the custom ObjectDataSource to use in your aspx pages as discussed above. This control also uses the classes GenericObjectDataSourceView and ExposedSr&lt;/li&gt;
&lt;li&gt;FileLogger and DebuggerWriter - classes for logging to text files and System.Debug.Out, see Logging section&lt;/li&gt;
&lt;li&gt;GenericDataSection - a class to handle configuration data&lt;/li&gt;
&lt;li&gt;Dynamic - some code to help in the sorting methods &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;NorthWindDataLayer&lt;/h3&gt;
This project is an example of how to use the code with your database (using Microsoft's NorthWind database), it references the GenericRepository project and contains all the project specific database classes that your application needs to work with. These are:
&lt;ul&gt;&lt;li&gt;Linq to Sql dbml file - In this case pointing to the NorthWind database&lt;/li&gt;
&lt;li&gt;Partial Entity classes which implements a custom data validation rules (see section on Error Handling) - In this project there is just one class Product which implements one rule &lt;/li&gt;
&lt;li&gt;Concrete Repository classes which inherit from GenericRepository and implement custom data access code for specific database entities - This project has two, ProductRepository and CategoryRepository &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;A test web project&lt;/h3&gt;
This project has one page with a GridView and a FormView which use the data layer via GenericObjectDataSources to list all the products in the Northwind database, allow editing and deletion of those projects, and insert new products via the FormView. &lt;br /&gt;
&lt;h3&gt;A console app&lt;/h3&gt;
To test functionality outside the context of a web application &lt;br /&gt;&lt;br /&gt;To run the example project:
&lt;ul&gt;&lt;li&gt;Download and unzip the release &lt;/li&gt;
&lt;li&gt;Open the solution in VS2008&lt;/li&gt;
&lt;li&gt;Change the connection string in the web.config to point to a Northwind database&lt;/li&gt;
&lt;li&gt;Run the web project&lt;/li&gt;&lt;/ul&gt;
&lt;br /&gt;To use the code in your own projects
&lt;ul&gt;&lt;li&gt;Create a class library to contain your Linq to Sql classes, partial entities and concrete repositories&lt;/li&gt;
&lt;li&gt;Run the T4 template as described above to create concrete repository classes&lt;/li&gt;
&lt;li&gt;Reference the GenericDataLayer project (either compiled or within your solution)&lt;/li&gt;
&lt;li&gt;Optionally define any new entity specific data access operations in your entity repository classes&lt;/li&gt;
&lt;li&gt;Make use of the GenericObjectDataSource to get easy inserts, updates, deletes, sorting and paging&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;</description><author>rbates</author><pubDate>Wed, 15 Apr 2009 12:57:27 GMT</pubDate><guid isPermaLink="false">Updated Wiki: Home 20090415125727P</guid></item><item><title>Updated Wiki: Home</title><link>http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=Home&amp;version=20</link><description>&lt;div class="wikidoc"&gt;&lt;h1&gt;Multi tier architecture for Linq to Sql&lt;/h1&gt;

&lt;h2&gt;Introduction&lt;/h2&gt;
This resource shows an approach for using Linq to Sql within a multi tier Asp.Net application, and particularly how it can be made to work well with ObjectDataSources. It is here as a discussion piece as well as a usable bit of code.&lt;br /&gt;&lt;br /&gt;The key features are a Request-scoped datacontext and entity repository classes which provide easy to use Create, Retrieve, Update and Delete (CRUD) operations implemented with Generics. Also included is a T4 template for auto generation of repositories from a dbml file. &lt;br /&gt;&lt;br /&gt;See here for a quick start &lt;a href="http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=code%20overview"&gt;introduction to using the code&lt;/a&gt;
&lt;h2&gt;Generic Entity Repository &lt;/h2&gt;
Each database entity has an associated repository class which is used to perform common CRUD operations. Specific entity repositorys inherit from a generic class &lt;i&gt;GenericRepository&lt;/i&gt; which already implements all the basic Select, Insert, Update &amp;amp; Delete operations.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
[System.ComponentModel.DataObject]
public class GenericRepository&amp;lt;TEntity, TDataContext&amp;gt; where TDataContext : DataContext
{
    public static List&amp;lt;TEntity&amp;gt; SelectAll()
    {
          ...
    }
    public static void Insert(TEntity entity)
    {
        ...
    }
    public static void Update(TEntity entity)
    {
        ...
    }
    public static void Delete(TEntity entity)
    {
        ...
    }
}
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Specific repositories then inherit from this by specifying the entity type which they are concerned with as well as the type of the DataContext used, as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;//ProductRepository class
public class ProductRepository : GenericRepository&amp;lt;Product, NorthwindDataContext&amp;gt;
{
}
&lt;/pre&gt;&lt;br /&gt;which allows client code such as the following:&lt;br /&gt;&lt;pre&gt;
   var productRepository = new ProductRepository();
   IList&amp;lt;Product&amp;gt; products = productRepository.SelectAll();
&lt;/pre&gt;&lt;br /&gt;The use of Generics means that I don't need to add any code at all into my ProductRepository to get all the standard CRUD operations in a fully type safe way. My ProductRepository class can now be customised to add any further data access methods which are specific to Products, for instance GetByCategoryId().&lt;br /&gt;There is also a class GenericStaticRepository which allows you to use this functionality in a static way so in the example above, rather than instantiating a ProductRepository I could simply do this:&lt;br /&gt;&lt;pre&gt;
   IList&amp;lt;Product&amp;gt; products = ProductStaticRepository.SelectAll();
&lt;/pre&gt;&lt;br /&gt;All of these concrete classes are auto generated by the T4 template included with the project as described below.&lt;br /&gt;
&lt;h2&gt;T4 Template&lt;/h2&gt;
Included in the source code is a &lt;a href="http://www.google.co.uk/search?hl=en&amp;amp;q=t4+templates&amp;amp;btnG=Google+Search&amp;amp;meta=&amp;amp;aq=0&amp;amp;oq=t4+tem" class="externalLink"&gt;T4 template&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; which will generate entities and concrete repositories (both static and non-static) with interfaces to facilitate testing. To use it you need to do the following:
&lt;ul&gt;&lt;li&gt;copy the files DataClasses.tt and L2ST4.ttinclude from the T4Templates directory into your project specific datalayer project&lt;/li&gt;
&lt;li&gt;ensure that DataClasses.tt has the same name as the dbml file (so in the example Northwind project DataClasses.tt has been renamed to Northwind.tt to match Northwind.dbml)&lt;/li&gt;
&lt;li&gt;to generate the classes, open DataClasses.tt (or whatever it is now called) and save it. You will probably get a dialog box asking if you are sure you  want to do this, click Ok. All the classes will then be generated in a file called &lt;i&gt;DataClasses.generated.cs&lt;/i&gt; where &lt;i&gt;DataClasses&lt;/i&gt; is the same as the name of your dbml file.&lt;/li&gt;&lt;/ul&gt;

&lt;h2&gt;Request scoped DataContext&lt;/h2&gt;
The second part of this solution is the request scoped DataContext. This is a pattern that is commonly used with the Hibernate OR mapper as well as elsewhere, and it means that there is only ever one DataContext per Http request which is stored in the HttpContext.Items collection. It is implemented as a protected property of the GenericRepository class as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
        protected static TDataContext DataContext
        {
            get
            {
                //We are in a web app, use a request scope
                if (HttpContext.Current != null)
                {
                    TDataContext dataContext = (TDataContext)HttpContext.Current.Items[DataContextKey];
                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        HttpContext.Current.Items.Add(DataContextKey, dataContext);
                    }
                    return dataContext;
                }
                else
                {

                    // Creates a Thread Scoped DataContext object that can be reused. 
                    // The DataContext is stored in Thread local storage.
                    // See here http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=361
                    //for a discussion of this code.

                    LocalDataStoreSlot threadData = Thread.GetNamedDataSlot(DataContextKey);
                    object dataContext = null;

                    if (threadData != null)
                        dataContext = Thread.GetData(threadData);

                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        if(threadData == null)
                            threadData = Thread.AllocateNamedDataSlot(DataContextKey);

                        Thread.SetData(threadData, dataContext);
                    }
                    return (TDataContext) dataContext;
                }

            }
        }
&lt;/pre&gt;&lt;br /&gt;As you can see from the code above it handles being used outside a web app by storing the DataContext in a named data slot on the thread it is running in.&lt;br /&gt;&lt;br /&gt;The usefulness of this approach can be seen if you consider a page which uses a number of ObjectDataSources; if we configure our ObjectDataSource to use the DataContext directly then each one will create and dispose of a new DataContext this will not only quickly become a performance overhead, but will also present us with a problem when specifying LoadOptions for the DataContext resulting in more complex, less maintainable code or quite possibly code which doesn't specify loading options at all.&lt;br /&gt;&lt;br /&gt;It should be noted that this approach means that if I have a CategoryRepository class as well as a ProductRepository class, both of which inherit from GenericRepository, both of these classes will use the same DataContext. In other words the DataContext is shared across the whole request, not just by one class type.&lt;br /&gt;
&lt;h2&gt;Custom ObjectDataSource&lt;/h2&gt;
In order for updates to work correctly with databinding it is advisable to use the GenericObjectDataSource control which is included in the DataLayer project. An ordinary ObjectDataSource control will create a new object before doing updates and if there are any unbound properties on this object, they will be left with their default values which will then be saved to the database, the GenericObjectDataSource control gets round this by retrieving the original values from the database, before updating them. For more discussions of the details behind this, see &lt;a href="https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488" class="externalLink"&gt;https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;Submitting changes&lt;/h2&gt;
Another feature of the Linq to Sql architecture is the way that changes are only submitted to the database when the SubmitChanges() method is called on the DataContext. This means that we must either decide at which point to call SubmitChanges() or delegate this responsibility to client code.&lt;br /&gt;To make the classes as flexible as possible any operations which require a call to SubmitChanges (Insert, Update and Delete), are provided with a boolean parameter which specify whether to submit changes immediately or not. There is also an overload of these methods without this parameter which is equivalent to passing true (again this makes use of ObjectDatasources much more straightforward).&lt;br /&gt;The SubmitChanges method of the DataContext is also exposed through the repository class to give Client code the ability to call this explicitly.&lt;br /&gt;
&lt;h2&gt;Sorting and Paging with GridViews&lt;/h2&gt;
There are a number of methods on the GenericRepository class to automatically support paging and sorting in GridViews.&lt;br /&gt;These are:&lt;br /&gt;&lt;pre&gt;
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(int maximumRows, int startRowIndex)
        {
            ...
        }
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression)
        {
         ...
        }
     
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression, int maximumRows, int startRowIndex)
        {
            ...
        }
        public static int Count()
        {
            ...
        }
&lt;/pre&gt;&lt;br /&gt;To use this functionality all you need to do is turn it on in the ObjectDataSource and GridView with the following attributes:&lt;br /&gt;ObjectDataSource: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
EnablePaging=&amp;quot;true&amp;quot; SelectCountMethod=&amp;quot;Count&amp;quot; SortParameterName=&amp;quot;sortExpression&amp;quot;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Gridview:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
AllowPaging=&amp;quot;true&amp;quot; AllowSorting=&amp;quot;true&amp;quot;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And hey presto it just works! This makes it really easy to create sortable, pagable GridViews with no extra coding.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;This release also includes some code from Scott Gu's blog to support Dynamic Querying, see &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx" class="externalLink"&gt;http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; for more details&lt;/i&gt;&lt;br /&gt;
&lt;h2&gt;Logging&lt;/h2&gt;
The code includes an easy way to configure Linq to Sql's logging feature (DataContext.Log) to write to either a text file or the System.Diagnostics.Debugger class which then appears in the output window within Visual Studio.&lt;br /&gt;&lt;br /&gt;To use this functionality you need to add the following lines into your web.config:&lt;br /&gt;&lt;br /&gt;In the &amp;lt;configSections&amp;gt; element:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
&amp;lt;section name=&amp;quot;GenericDataSection&amp;quot; type=&amp;quot;DataLayer.GenericDataSection, DataLayer&amp;quot; allowDefinition=&amp;quot;MachineToApplication&amp;quot; restartOnExternalChanges=&amp;quot;true&amp;quot; requirePermission=&amp;quot;false&amp;quot;/&amp;gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then directly after &amp;lt;configSections&amp;gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
&amp;lt;GenericDataSection LogType=&amp;quot;file&amp;quot; LogFile=&amp;quot;C:\Projects\MultiTierLinqToSql_release\test.txt&amp;quot; DeleteExistingFile=&amp;quot;true&amp;quot;/&amp;gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The first of these lines just declares the second line which is the one that contains the interesting stuff.&lt;br /&gt;There are 3 config options in this section:
&lt;ol&gt;&lt;li&gt;LogType - this can be either 'file' (logs output to a file), 'debug' (logs output to Systems.Diagnostics.Debug) or 'none' (switches logging off). &lt;/li&gt;
&lt;li&gt;LogFile - only applies when LogType is set to 'file', and the default is 'log.txt' it specifies the name of the file to use for logging.&lt;/li&gt;
&lt;li&gt;DeleteExistingFile - only applies when LogType is set to 'file', values can be 'true' or 'false', and the default is true. When this is set to true the file will be overwritten every time a new DataContext is created, effectively once per request. If set to false then all output is appended to the end of the file. This can result in a very large log files so be careful.&lt;/li&gt;&lt;/ol&gt;
&lt;h4&gt;Notes&lt;/h4&gt;
As with all file logging this can be pretty detrimental to performance and so should not be left on in production.&lt;br /&gt;&lt;br /&gt;To handle the logging to the output window I have used the DebuggerWriter class described here: &lt;a href="http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11" class="externalLink"&gt;http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;Error Handling&lt;/h2&gt;
Best practice for managing business rules relating to data integrity with Linq to Sql is to include these rules in partial methods in the entity classes and throw exceptions when they are violated (see http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx for more details).&lt;br /&gt;When using this strategy with an ObjectDataSource, you can then catch these exceptions in the OnUpdated or OnInserted events of your ObjectDataSource and present the information to the user. &lt;br /&gt;To do so you set the OnUpdated and/or the OnInserted attribute of your GenericObjectDatasource:&lt;br /&gt;&lt;pre&gt;
OnUpdated=&amp;quot;ProductDataSource_Updated&amp;quot;
OnInserted=&amp;quot;ProductDataSource_Updated&amp;quot;
&lt;/pre&gt;&lt;br /&gt;and then handle this event in your code behind:&lt;br /&gt;&lt;pre&gt;
protected void ProductDataSource_Updated(object sender, ObjectDataSourceStatusEventArgs e)
    {
        if (e.Exception != null)
        {
            //litError is a literal control which I want to use to display the error to the user
            litError.Text = e.Exception.Message;
            //This tells the objectDataSource that I have handled the error and not to throw it
            e.ExceptionHandled = true;
        }
    }
&lt;/pre&gt;&lt;br /&gt;There is an example of this in the Default.aspx page in the test website.&lt;br /&gt;
&lt;h2&gt;DataLoadOptions&lt;/h2&gt;
As has been widely noted, the way that Linq to Sql works, means that the DataLoadOptions for your DataContext need to be set &lt;i&gt;before&lt;/i&gt; any operations are carried out, and cannot subsequently be changed. This means that in my Asp.Net application I will need to set the DataLoadOptions for the whole request somewhere near the start (assuming of course that I need to set DataLoadOptions at all). It also means that my UI or business layer will need to take responsibility for this. &lt;br /&gt;&lt;br /&gt;What this means in practice is that in a classic Web forms type app I will probably set the DataLoadOptions in the OnInit event of my page, if I'm using MVC then my controller will do it. &lt;br /&gt;
&lt;h2&gt;The code&lt;/h2&gt;
The code consists of 4 projects; GenericDataLayer, which contains the reusable code and 3 demo/test projects
&lt;h3&gt;GenericDataLayer&lt;/h3&gt;
This project contains all of the code you need to use this solution, it can be compiled and referenced in your projects or run as a project within your solutions.&lt;br /&gt;It is made up of:
&lt;ul&gt;&lt;li&gt;GenericRepository class - the main class which implements the generic CRUD methods as discussed above&lt;/li&gt;
&lt;li&gt;GenericObjectDataSource - the custom ObjectDataSource to use in your aspx pages as discussed above. This control also uses the classes GenericObjectDataSourceView and ExposedSr&lt;/li&gt;
&lt;li&gt;FileLogger and DebuggerWriter - classes for logging to text files and System.Debug.Out, see Logging section&lt;/li&gt;
&lt;li&gt;GenericDataSection - a class to handle configuration data&lt;/li&gt;
&lt;li&gt;Dynamic - some code to help in the sorting methods &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;NorthWindDataLayer&lt;/h3&gt;
This project is an example of how to use the code with your database (using Microsoft's NorthWind database), it references the GenericRepository project and contains all the project specific database classes that your application needs to work with. These are:
&lt;ul&gt;&lt;li&gt;Linq to Sql dbml file - In this case pointing to the NorthWind database&lt;/li&gt;
&lt;li&gt;Partial Entity classes which implements a custom data validation rules (see section on Error Handling) - In this project there is just one class Product which implements one rule &lt;/li&gt;
&lt;li&gt;Concrete Repository classes which inherit from GenericRepository and implement custom data access code for specific database entities - This project has two, ProductRepository and CategoryRepository &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;A test web project&lt;/h3&gt;
This project has one page with a GridView and a FormView which use the data layer via GenericObjectDataSources to list all the products in the Northwind database, allow editing and deletion of those projects, and insert new products via the FormView. &lt;br /&gt;
&lt;h3&gt;A console app&lt;/h3&gt;
To test functionality outside the context of a web application &lt;br /&gt;&lt;br /&gt;To run the example project:
&lt;ul&gt;&lt;li&gt;Download and unzip the release &lt;/li&gt;
&lt;li&gt;Open the solution in VS2008&lt;/li&gt;
&lt;li&gt;Change the connection string in the web.config to point to a Northwind database&lt;/li&gt;
&lt;li&gt;Run the web project&lt;/li&gt;&lt;/ul&gt;
&lt;br /&gt;To use the code in your own projects
&lt;ul&gt;&lt;li&gt;Create a class library to contain your Linq to Sql classes, partial entities and concrete repositories&lt;/li&gt;
&lt;li&gt;Run the T4 template as described above to create concrete repository classes&lt;/li&gt;
&lt;li&gt;Reference the GenericDataLayer project (either compiled or within your solution)&lt;/li&gt;
&lt;li&gt;Optionally define any new entity specific data access operations in your entity repository classes&lt;/li&gt;
&lt;li&gt;Make use of the GenericObjectDataSource to get easy inserts, updates, deletes, sorting and paging&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;</description><author>rbates</author><pubDate>Tue, 14 Apr 2009 13:22:35 GMT</pubDate><guid isPermaLink="false">Updated Wiki: Home 20090414012235P</guid></item><item><title>Updated Wiki: code overview</title><link>http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=code overview&amp;version=3</link><description>&lt;div class="wikidoc"&gt;&lt;h1&gt;The code&lt;/h1&gt;
The code consists of 4 projects; GenericDataLayer, which contains the reusable code and 3 demo/test projects. There is also a folder containing the T4 templates discussed in the introduction to the code.&lt;br /&gt;
&lt;h3&gt;GenericDataLayer&lt;/h3&gt;
This project contains all of the code you need to use this solution, it can be compiled and referenced in your projects or run as a project within your solutions.&lt;br /&gt;It is made up of:
&lt;ul&gt;&lt;li&gt;GenericRepository class - the main class which implements the generic CRUD methods as discussed above&lt;/li&gt;
&lt;li&gt;GenericObjectDataSource - the custom ObjectDataSource to use in your aspx pages as discussed above. This control also uses the classes GenericObjectDataSourceView and ExposedSr&lt;/li&gt;
&lt;li&gt;FileLogger and DebuggerWriter - classes for logging to text files and System.Debug.Out, see Logging section&lt;/li&gt;
&lt;li&gt;GenericDataSection - a class to handle configuration data&lt;/li&gt;
&lt;li&gt;Dynamic - some code to help in the sorting methods &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;NorthWindDataLayer&lt;/h3&gt;
This project is an example of how to use the code with your database (using Microsoft's NorthWind database), it references the GenericRepository project and contains all the project specific database classes that your application needs to work with. These are:
&lt;ul&gt;&lt;li&gt;Linq to Sql dbml file - In this case pointing to the NorthWind database&lt;/li&gt;
&lt;li&gt;Partial Entity classes which implements a custom data validation rules (see section on Error Handling) - In this project there is just one class Product which implements one rule &lt;/li&gt;
&lt;li&gt;Concrete Repository classes which inherit from GenericRepository and implement custom data access code for specific database entities - This project has two, ProductRepository and CategoryRepository &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;A test web project&lt;/h3&gt;
This project has one page with a GridView and a FormView which use the data layer via GenericObjectDataSources to list all the products in the Northwind database, allow editing and deletion of those projects, and insert new products via the FormView. &lt;br /&gt;
&lt;h3&gt;A console app&lt;/h3&gt;
To test functionality outside the context of a web application &lt;br /&gt;
&lt;h2&gt;To run the example project:&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;Check out the code or download and unzip the release&lt;/li&gt;
&lt;li&gt;Open the solution in VS2008&lt;/li&gt;
&lt;li&gt;Change the connection string in the web.config to point to a Northwind database&lt;/li&gt;
&lt;li&gt;Run the web project&lt;/li&gt;&lt;/ul&gt;

&lt;h2&gt;To use the code in your own projects&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;Create a class library to contain your Linq to Sql classes, partial entities and concrete repositories&lt;/li&gt;
&lt;li&gt;Run the T4 template as described above to create concrete repository classes&lt;/li&gt;
&lt;li&gt;Reference the GenericDataLayer project (either compiled or within your solution)&lt;/li&gt;
&lt;li&gt;Optionally define any new entity specific data access operations in your entity repository classes&lt;/li&gt;
&lt;li&gt;Make use of the GenericObjectDataSource to get easy inserts, updates, deletes, sorting and paging&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;</description><author>rbates</author><pubDate>Tue, 14 Apr 2009 13:10:04 GMT</pubDate><guid isPermaLink="false">Updated Wiki: code overview 20090414011004P</guid></item><item><title>Updated Wiki: code overview</title><link>http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=code overview&amp;version=2</link><description>&lt;div class="wikidoc"&gt;&lt;h2&gt;The code&lt;/h2&gt;
The code consists of 4 projects; GenericDataLayer, which contains the reusable code and 3 demo/test projects. There is also a folder containing the T4 templates discussed in the introduction to the code.&lt;br /&gt;
&lt;h3&gt;GenericDataLayer&lt;/h3&gt;
This project contains all of the code you need to use this solution, it can be compiled and referenced in your projects or run as a project within your solutions.&lt;br /&gt;It is made up of:
&lt;ul&gt;&lt;li&gt;GenericRepository class - the main class which implements the generic CRUD methods as discussed above&lt;/li&gt;
&lt;li&gt;GenericObjectDataSource - the custom ObjectDataSource to use in your aspx pages as discussed above. This control also uses the classes GenericObjectDataSourceView and ExposedSr&lt;/li&gt;
&lt;li&gt;FileLogger and DebuggerWriter - classes for logging to text files and System.Debug.Out, see Logging section&lt;/li&gt;
&lt;li&gt;GenericDataSection - a class to handle configuration data&lt;/li&gt;
&lt;li&gt;Dynamic - some code to help in the sorting methods &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;NorthWindDataLayer&lt;/h3&gt;
This project is an example of how to use the code with your database (using Microsoft's NorthWind database), it references the GenericRepository project and contains all the project specific database classes that your application needs to work with. These are:
&lt;ul&gt;&lt;li&gt;Linq to Sql dbml file - In this case pointing to the NorthWind database&lt;/li&gt;
&lt;li&gt;Partial Entity classes which implements a custom data validation rules (see section on Error Handling) - In this project there is just one class Product which implements one rule &lt;/li&gt;
&lt;li&gt;Concrete Repository classes which inherit from GenericRepository and implement custom data access code for specific database entities - This project has two, ProductRepository and CategoryRepository &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;A test web project&lt;/h3&gt;
This project has one page with a GridView and a FormView which use the data layer via GenericObjectDataSources to list all the products in the Northwind database, allow editing and deletion of those projects, and insert new products via the FormView. &lt;br /&gt;
&lt;h3&gt;A console app&lt;/h3&gt;
To test functionality outside the context of a web application &lt;br /&gt;
&lt;h2&gt;To run the example project:&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;Check out the code or download and unzip the release&lt;/li&gt;
&lt;li&gt;Open the solution in VS2008&lt;/li&gt;
&lt;li&gt;Change the connection string in the web.config to point to a Northwind database&lt;/li&gt;
&lt;li&gt;Run the web project&lt;/li&gt;&lt;/ul&gt;

&lt;h2&gt;To use the code in your own projects&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;Create a class library to contain your Linq to Sql classes, partial entities and concrete repositories&lt;/li&gt;
&lt;li&gt;Run the T4 template as described above to create concrete repository classes&lt;/li&gt;
&lt;li&gt;Reference the GenericDataLayer project (either compiled or within your solution)&lt;/li&gt;
&lt;li&gt;Optionally define any new entity specific data access operations in your entity repository classes&lt;/li&gt;
&lt;li&gt;Make use of the GenericObjectDataSource to get easy inserts, updates, deletes, sorting and paging&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;</description><author>rbates</author><pubDate>Tue, 14 Apr 2009 12:04:34 GMT</pubDate><guid isPermaLink="false">Updated Wiki: code overview 20090414120434P</guid></item><item><title>Updated Wiki: code overview</title><link>http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=code overview&amp;version=1</link><description>&lt;div class="wikidoc"&gt;&lt;h2&gt;The code&lt;/h2&gt;
The code consists of 4 projects; GenericDataLayer, which contains the reusable code and 3 demo/test projects. There is also a folder containing the T4 templates discussed in the introduction to the code.&lt;br /&gt;
&lt;h3&gt;GenericDataLayer&lt;/h3&gt;
This project contains all of the code you need to use this solution, it can be compiled and referenced in your projects or run as a project within your solutions.&lt;br /&gt;It is made up of:
&lt;ul&gt;&lt;li&gt;GenericRepository class - the main class which implements the generic CRUD methods as discussed above&lt;/li&gt;
&lt;li&gt;GenericObjectDataSource - the custom ObjectDataSource to use in your aspx pages as discussed above. This control also uses the classes GenericObjectDataSourceView and ExposedSr&lt;/li&gt;
&lt;li&gt;FileLogger and DebuggerWriter - classes for logging to text files and System.Debug.Out, see Logging section&lt;/li&gt;
&lt;li&gt;GenericDataSection - a class to handle configuration data&lt;/li&gt;
&lt;li&gt;Dynamic - some code to help in the sorting methods &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;NorthWindDataLayer&lt;/h3&gt;
This project is an example of how to use the code with your database (using Microsoft's NorthWind database), it references the GenericRepository project and contains all the project specific database classes that your application needs to work with. These are:
&lt;ul&gt;&lt;li&gt;Linq to Sql dbml file - In this case pointing to the NorthWind database&lt;/li&gt;
&lt;li&gt;Partial Entity classes which implements a custom data validation rules (see section on Error Handling) - In this project there is just one class Product which implements one rule &lt;/li&gt;
&lt;li&gt;Concrete Repository classes which inherit from GenericRepository and implement custom data access code for specific database entities - This project has two, ProductRepository and CategoryRepository &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;A test web project&lt;/h3&gt;
This project has one page with a GridView and a FormView which use the data layer via GenericObjectDataSources to list all the products in the Northwind database, allow editing and deletion of those projects, and insert new products via the FormView. &lt;br /&gt;
&lt;h3&gt;A console app&lt;/h3&gt;
To test functionality outside the context of a web application &lt;br /&gt;
&lt;h2&gt;To run the example project:&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;Download and unzip the release &lt;/li&gt;
&lt;li&gt;Open the solution in VS2008&lt;/li&gt;
&lt;li&gt;Change the connection string in the web.config to point to a Northwind database&lt;/li&gt;
&lt;li&gt;Run the web project&lt;/li&gt;&lt;/ul&gt;

&lt;h2&gt;To use the code in your own projects&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;Create a class library to contain your Linq to Sql classes, partial entities and concrete repositories&lt;/li&gt;
&lt;li&gt;Run the T4 template as described above to create concrete repository classes&lt;/li&gt;
&lt;li&gt;Reference the GenericDataLayer project (either compiled or within your solution)&lt;/li&gt;
&lt;li&gt;Optionally define any new entity specific data access operations in your entity repository classes&lt;/li&gt;
&lt;li&gt;Make use of the GenericObjectDataSource to get easy inserts, updates, deletes, sorting and paging&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;</description><author>rbates</author><pubDate>Tue, 14 Apr 2009 12:01:32 GMT</pubDate><guid isPermaLink="false">Updated Wiki: code overview 20090414120132P</guid></item><item><title>Updated Wiki: Home</title><link>http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=Home&amp;version=19</link><description>&lt;div class="wikidoc"&gt;&lt;h1&gt;Multi tier architecture for Linq to Sql&lt;/h1&gt;

&lt;h2&gt;Introduction&lt;/h2&gt;
This resource shows an approach for using Linq to Sql within a multi tier Asp.Net application, and particularly how it can be made to work well with ObjectDataSources. It is here as a discussion piece as well as a usable bit of code.&lt;br /&gt;&lt;br /&gt;The key features are a Request-scoped datacontext and entity repository classes which provide easy to use Create, Retrieve, Update and Delete (CRUD) operations implemented with Generics. Also included is a T4 template for auto generation of repositories from a dbml file. &lt;br /&gt;&lt;br /&gt;See here for a quick start &lt;a href="http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=code%20overview"&gt;introduction to using the code&lt;/a&gt;
&lt;h2&gt;Entity Repository classes&lt;/h2&gt;
Each database entity has an associated repository class which is used to perform common CRUD operations. Specific entity repositorys inherit from a generic class &lt;i&gt;GenericRepository&lt;/i&gt; which already implements all the basic Select, Insert, Update &amp;amp; Delete operations.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
[System.ComponentModel.DataObject]
public class GenericRepository&amp;lt;TEntity, TDataContext&amp;gt; where TDataContext : DataContext
{
    public static List&amp;lt;TEntity&amp;gt; SelectAll()
    {
          ...
    }
    public static void Insert(TEntity entity)
    {
        ...
    }
    public static void Update(TEntity entity)
    {
        ...
    }
    public static void Delete(TEntity entity)
    {
        ...
    }
}
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Specific repositories then inherit from this by specifying the entity type which they are concerned with as well as the type of the DataContext used, as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;//ProductRepository class
public class ProductRepository : GenericRepository&amp;lt;Product, NorthwindDataContext&amp;gt;
{
}
&lt;/pre&gt;&lt;br /&gt;which allows client code such as the following:&lt;br /&gt;&lt;pre&gt;
   var productRepository = new ProductRepository();
   IList&amp;lt;Product&amp;gt; products = productRepository.SelectAll();
&lt;/pre&gt;&lt;br /&gt;The use of Generics means that I don't need to add any code at all into my ProductRepository to get all the standard CRUD operations in a fully type safe way. My ProductRepository class can now be customised to add any further data access methods which are specific to Products, for instance GetByCategoryId().&lt;br /&gt;There is also a class GenericStaticRepository which allows you to use this functionality in a static way so in the example above, rather than instantiating a ProductRepository I could simply do this:&lt;br /&gt;&lt;pre&gt;
   IList&amp;lt;Product&amp;gt; products = ProductStaticRepository.SelectAll();
&lt;/pre&gt;&lt;br /&gt;All of these concrete classes are auto generated by the T4 template included with the project as described below.&lt;br /&gt;
&lt;h2&gt;T4 Template&lt;/h2&gt;
Included in the source code is a &lt;a href="http://www.google.co.uk/search?hl=en&amp;amp;q=t4+templates&amp;amp;btnG=Google+Search&amp;amp;meta=&amp;amp;aq=0&amp;amp;oq=t4+tem" class="externalLink"&gt;T4 template&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; which will generate entities and concrete repositories (both static and non-static) with interfaces to facilitate testing. To use it you need to do the following:
&lt;ul&gt;&lt;li&gt;copy the files DataClasses.tt and L2ST4.ttinclude from the T4Templates directory into your project specific datalayer project&lt;/li&gt;
&lt;li&gt;ensure that DataClasses.tt has the same name as the dbml file (so in the example Northwind project DataClasses.tt has been renamed to Northwind.tt to match Northwind.dbml)&lt;/li&gt;
&lt;li&gt;to generate the classes, open DataClasses.tt (or whatever it is now called) and save it. You will probably get a dialog box asking if you are sure you  want to do this, click Ok. All the classes will then be generated in a file called &lt;i&gt;DataClasses.generated.cs&lt;/i&gt; where &lt;i&gt;DataClasses&lt;/i&gt; is the same as the name of your dbml file.&lt;/li&gt;&lt;/ul&gt;

&lt;h2&gt;Request scoped DataContext&lt;/h2&gt;
The second part of this solution is the request scoped DataContext. This is a pattern that is commonly used with the Hibernate OR mapper as well as elsewhere, and it means that there is only ever one DataContext per Http request which is stored in the HttpContext.Items collection. It is implemented as a protected property of the GenericRepository class as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
        protected static TDataContext DataContext
        {
            get
            {
                //We are in a web app, use a request scope
                if (HttpContext.Current != null)
                {
                    TDataContext dataContext = (TDataContext)HttpContext.Current.Items[DataContextKey];
                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        HttpContext.Current.Items.Add(DataContextKey, dataContext);
                    }
                    return dataContext;
                }
                else
                {

                    // Creates a Thread Scoped DataContext object that can be reused. 
                    // The DataContext is stored in Thread local storage.
                    // See here http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=361
                    //for a discussion of this code.

                    LocalDataStoreSlot threadData = Thread.GetNamedDataSlot(DataContextKey);
                    object dataContext = null;

                    if (threadData != null)
                        dataContext = Thread.GetData(threadData);

                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        if(threadData == null)
                            threadData = Thread.AllocateNamedDataSlot(DataContextKey);

                        Thread.SetData(threadData, dataContext);
                    }
                    return (TDataContext) dataContext;
                }

            }
        }
&lt;/pre&gt;&lt;br /&gt;As you can see from the code above it handles being used outside a web app by storing the DataContext in a named data slot on the thread it is running in.&lt;br /&gt;&lt;br /&gt;The usefulness of this approach can be seen if you consider a page which uses a number of ObjectDataSources; if we configure our ObjectDataSource to use the DataContext directly then each one will create and dispose of a new DataContext this will not only quickly become a performance overhead, but will also present us with a problem when specifying LoadOptions for the DataContext resulting in more complex, less maintainable code or quite possibly code which doesn't specify loading options at all.&lt;br /&gt;&lt;br /&gt;It should be noted that this approach means that if I have a CategoryRepository class as well as a ProductRepository class, both of which inherit from GenericRepository, both of these classes will use the same DataContext. In other words the DataContext is shared across the whole request, not just by one class type.&lt;br /&gt;
&lt;h2&gt;Custom ObjectDataSource&lt;/h2&gt;
In order for updates to work correctly with databinding it is advisable to use the GenericObjectDataSource control which is included in the DataLayer project. An ordinary ObjectDataSource control will create a new object before doing updates and if there are any unbound properties on this object, they will be left with their default values which will then be saved to the database, the GenericObjectDataSource control gets round this by retrieving the original values from the database, before updating them. For more discussions of the details behind this, see &lt;a href="https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488" class="externalLink"&gt;https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;Submitting changes&lt;/h2&gt;
Another feature of the Linq to Sql architecture is the way that changes are only submitted to the database when the SubmitChanges() method is called on the DataContext. This means that we must either decide at which point to call SubmitChanges() or delegate this responsibility to client code.&lt;br /&gt;To make the classes as flexible as possible any operations which require a call to SubmitChanges (Insert, Update and Delete), are provided with a boolean parameter which specify whether to submit changes immediately or not. There is also an overload of these methods without this parameter which is equivalent to passing true (again this makes use of ObjectDatasources much more straightforward).&lt;br /&gt;The SubmitChanges method of the DataContext is also exposed through the repository class to give Client code the ability to call this explicitly.&lt;br /&gt;
&lt;h2&gt;Sorting and Paging with GridViews&lt;/h2&gt;
There are a number of methods on the GenericRepository class to automatically support paging and sorting in GridViews.&lt;br /&gt;These are:&lt;br /&gt;&lt;pre&gt;
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(int maximumRows, int startRowIndex)
        {
            ...
        }
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression)
        {
         ...
        }
     
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression, int maximumRows, int startRowIndex)
        {
            ...
        }
        public static int Count()
        {
            ...
        }
&lt;/pre&gt;&lt;br /&gt;To use this functionality all you need to do is turn it on in the ObjectDataSource and GridView with the following attributes:&lt;br /&gt;ObjectDataSource: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
EnablePaging=&amp;quot;true&amp;quot; SelectCountMethod=&amp;quot;Count&amp;quot; SortParameterName=&amp;quot;sortExpression&amp;quot;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Gridview:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
AllowPaging=&amp;quot;true&amp;quot; AllowSorting=&amp;quot;true&amp;quot;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And hey presto it just works! This makes it really easy to create sortable, pagable GridViews with no extra coding.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;This release also includes some code from Scott Gu's blog to support Dynamic Querying, see &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx" class="externalLink"&gt;http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; for more details&lt;/i&gt;&lt;br /&gt;
&lt;h2&gt;Logging&lt;/h2&gt;
The code includes an easy way to configure Linq to Sql's logging feature (DataContext.Log) to write to either a text file or the System.Diagnostics.Debugger class which then appears in the output window within Visual Studio.&lt;br /&gt;&lt;br /&gt;To use this functionality you need to add the following lines into your web.config:&lt;br /&gt;&lt;br /&gt;In the &amp;lt;configSections&amp;gt; element:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
&amp;lt;section name=&amp;quot;GenericDataSection&amp;quot; type=&amp;quot;DataLayer.GenericDataSection, DataLayer&amp;quot; allowDefinition=&amp;quot;MachineToApplication&amp;quot; restartOnExternalChanges=&amp;quot;true&amp;quot; requirePermission=&amp;quot;false&amp;quot;/&amp;gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then directly after &amp;lt;configSections&amp;gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
&amp;lt;GenericDataSection LogType=&amp;quot;file&amp;quot; LogFile=&amp;quot;C:\Projects\MultiTierLinqToSql_release\test.txt&amp;quot; DeleteExistingFile=&amp;quot;true&amp;quot;/&amp;gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The first of these lines just declares the second line which is the one that contains the interesting stuff.&lt;br /&gt;There are 3 config options in this section:
&lt;ol&gt;&lt;li&gt;LogType - this can be either 'file' (logs output to a file), 'debug' (logs output to Systems.Diagnostics.Debug) or 'none' (switches logging off). &lt;/li&gt;
&lt;li&gt;LogFile - only applies when LogType is set to 'file', and the default is 'log.txt' it specifies the name of the file to use for logging.&lt;/li&gt;
&lt;li&gt;DeleteExistingFile - only applies when LogType is set to 'file', values can be 'true' or 'false', and the default is true. When this is set to true the file will be overwritten every time a new DataContext is created, effectively once per request. If set to false then all output is appended to the end of the file. This can result in a very large log files so be careful.&lt;/li&gt;&lt;/ol&gt;
&lt;h4&gt;Notes&lt;/h4&gt;
As with all file logging this can be pretty detrimental to performance and so should not be left on in production.&lt;br /&gt;&lt;br /&gt;To handle the logging to the output window I have used the DebuggerWriter class described here: &lt;a href="http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11" class="externalLink"&gt;http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;Error Handling&lt;/h2&gt;
Best practice for managing business rules relating to data integrity with Linq to Sql is to include these rules in partial methods in the entity classes and throw exceptions when they are violated (see http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx for more details).&lt;br /&gt;When using this strategy with an ObjectDataSource, you can then catch these exceptions in the OnUpdated or OnInserted events of your ObjectDataSource and present the information to the user. &lt;br /&gt;To do so you set the OnUpdated and/or the OnInserted attribute of your GenericObjectDatasource:&lt;br /&gt;&lt;pre&gt;
OnUpdated=&amp;quot;ProductDataSource_Updated&amp;quot;
OnInserted=&amp;quot;ProductDataSource_Updated&amp;quot;
&lt;/pre&gt;&lt;br /&gt;and then handle this event in your code behind:&lt;br /&gt;&lt;pre&gt;
protected void ProductDataSource_Updated(object sender, ObjectDataSourceStatusEventArgs e)
    {
        if (e.Exception != null)
        {
            //litError is a literal control which I want to use to display the error to the user
            litError.Text = e.Exception.Message;
            //This tells the objectDataSource that I have handled the error and not to throw it
            e.ExceptionHandled = true;
        }
    }
&lt;/pre&gt;&lt;br /&gt;There is an example of this in the Default.aspx page in the test website.&lt;br /&gt;
&lt;h2&gt;DataLoadOptions&lt;/h2&gt;
As has been widely noted, the way that Linq to Sql works, means that the DataLoadOptions for your DataContext need to be set &lt;i&gt;before&lt;/i&gt; any operations are carried out, and cannot subsequently be changed. This means that in my Asp.Net application I will need to set the DataLoadOptions for the whole request somewhere near the start (assuming of course that I need to set DataLoadOptions at all). It also means that my UI or business layer will need to take responsibility for this. &lt;br /&gt;&lt;br /&gt;What this means in practice is that in a classic Web forms type app I will probably set the DataLoadOptions in the OnInit event of my page, if I'm using MVC then my controller will do it. &lt;br /&gt;
&lt;h2&gt;The code&lt;/h2&gt;
The code consists of 4 projects; GenericDataLayer, which contains the reusable code and 3 demo/test projects
&lt;h3&gt;GenericDataLayer&lt;/h3&gt;
This project contains all of the code you need to use this solution, it can be compiled and referenced in your projects or run as a project within your solutions.&lt;br /&gt;It is made up of:
&lt;ul&gt;&lt;li&gt;GenericRepository class - the main class which implements the generic CRUD methods as discussed above&lt;/li&gt;
&lt;li&gt;GenericObjectDataSource - the custom ObjectDataSource to use in your aspx pages as discussed above. This control also uses the classes GenericObjectDataSourceView and ExposedSr&lt;/li&gt;
&lt;li&gt;FileLogger and DebuggerWriter - classes for logging to text files and System.Debug.Out, see Logging section&lt;/li&gt;
&lt;li&gt;GenericDataSection - a class to handle configuration data&lt;/li&gt;
&lt;li&gt;Dynamic - some code to help in the sorting methods &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;NorthWindDataLayer&lt;/h3&gt;
This project is an example of how to use the code with your database (using Microsoft's NorthWind database), it references the GenericRepository project and contains all the project specific database classes that your application needs to work with. These are:
&lt;ul&gt;&lt;li&gt;Linq to Sql dbml file - In this case pointing to the NorthWind database&lt;/li&gt;
&lt;li&gt;Partial Entity classes which implements a custom data validation rules (see section on Error Handling) - In this project there is just one class Product which implements one rule &lt;/li&gt;
&lt;li&gt;Concrete Repository classes which inherit from GenericRepository and implement custom data access code for specific database entities - This project has two, ProductRepository and CategoryRepository &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;A test web project&lt;/h3&gt;
This project has one page with a GridView and a FormView which use the data layer via GenericObjectDataSources to list all the products in the Northwind database, allow editing and deletion of those projects, and insert new products via the FormView. &lt;br /&gt;
&lt;h3&gt;A console app&lt;/h3&gt;
To test functionality outside the context of a web application &lt;br /&gt;&lt;br /&gt;To run the example project:
&lt;ul&gt;&lt;li&gt;Download and unzip the release &lt;/li&gt;
&lt;li&gt;Open the solution in VS2008&lt;/li&gt;
&lt;li&gt;Change the connection string in the web.config to point to a Northwind database&lt;/li&gt;
&lt;li&gt;Run the web project&lt;/li&gt;&lt;/ul&gt;
&lt;br /&gt;To use the code in your own projects
&lt;ul&gt;&lt;li&gt;Create a class library to contain your Linq to Sql classes, partial entities and concrete repositories&lt;/li&gt;
&lt;li&gt;Run the T4 template as described above to create concrete repository classes&lt;/li&gt;
&lt;li&gt;Reference the GenericDataLayer project (either compiled or within your solution)&lt;/li&gt;
&lt;li&gt;Optionally define any new entity specific data access operations in your entity repository classes&lt;/li&gt;
&lt;li&gt;Make use of the GenericObjectDataSource to get easy inserts, updates, deletes, sorting and paging&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;</description><author>rbates</author><pubDate>Tue, 14 Apr 2009 11:59:27 GMT</pubDate><guid isPermaLink="false">Updated Wiki: Home 20090414115927A</guid></item><item><title>Updated Wiki: Home</title><link>http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=Home&amp;version=18</link><description>&lt;div class="wikidoc"&gt;&lt;h1&gt;Multi tier architecture for Linq to Sql&lt;/h1&gt;

&lt;h2&gt;Introduction&lt;/h2&gt;
This resource shows an approach for using Linq to Sql within a multi tier Asp.Net application, and particularly how it can be made to work well with ObjectDataSources. It is here as a discussion piece as well as a usable bit of code.&lt;br /&gt;&lt;br /&gt;The key features are a Request-scoped datacontext and entity repository classes which provide easy to use Create, Retrieve, Update and Delete (CRUD) operations implemented with Generics. Also included is a T4 template for auto generation of repositories from a dbml file. &lt;br /&gt;
&lt;h2&gt;Entity Repository classes&lt;/h2&gt;
Each database entity has an associated repository class which is used to perform common CRUD operations. Specific entity repositorys inherit from a generic class &lt;i&gt;GenericRepository&lt;/i&gt; which already implements all the basic Select, Insert, Update &amp;amp; Delete operations.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
[System.ComponentModel.DataObject]
public class GenericRepository&amp;lt;TEntity, TDataContext&amp;gt; where TDataContext : DataContext
{
    public static List&amp;lt;TEntity&amp;gt; SelectAll()
    {
          ...
    }
    public static void Insert(TEntity entity)
    {
        ...
    }
    public static void Update(TEntity entity)
    {
        ...
    }
    public static void Delete(TEntity entity)
    {
        ...
    }
}
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Specific repositories then inherit from this by specifying the entity type which they are concerned with as well as the type of the DataContext used, as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;//ProductRepository class
public class ProductRepository : GenericRepository&amp;lt;Product, NorthwindDataContext&amp;gt;
{
}
&lt;/pre&gt;&lt;br /&gt;which allows client code such as the following:&lt;br /&gt;&lt;pre&gt;
   var productRepository = new ProductRepository();
   IList&amp;lt;Product&amp;gt; products = productRepository.SelectAll();
&lt;/pre&gt;&lt;br /&gt;The use of Generics means that I don't need to add any code at all into my ProductRepository to get all the standard CRUD operations in a fully type safe way. My ProductRepository class can now be customised to add any further data access methods which are specific to Products, for instance GetByCategoryId().&lt;br /&gt;There is also a class GenericStaticRepository which allows you to use this functionality in a static way so in the example above, rather than instantiating a ProductRepository I could simply do this:&lt;br /&gt;&lt;pre&gt;
   IList&amp;lt;Product&amp;gt; products = ProductStaticRepository.SelectAll();
&lt;/pre&gt;&lt;br /&gt;All of these concrete classes are auto generated by the T4 template included with the project as described below.&lt;br /&gt;
&lt;h2&gt;T4 Template&lt;/h2&gt;
Included in the source code is a &lt;a href="http://www.google.co.uk/search?hl=en&amp;amp;q=t4+templates&amp;amp;btnG=Google+Search&amp;amp;meta=&amp;amp;aq=0&amp;amp;oq=t4+tem" class="externalLink"&gt;T4 template&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; which will generate entities and concrete repositories (both static and non-static) with interfaces to facilitate testing. To use it you need to do the following:
&lt;ul&gt;&lt;li&gt;copy the files DataClasses.tt and L2ST4.ttinclude from the T4Templates directory into your project specific datalayer project&lt;/li&gt;
&lt;li&gt;ensure that DataClasses.tt has the same name as the dbml file (so in the example Northwind project DataClasses.tt has been renamed to Northwind.tt to match Northwind.dbml)&lt;/li&gt;
&lt;li&gt;to generate the classes, open DataClasses.tt (or whatever it is now called) and save it. You will probably get a dialog box asking if you are sure you  want to do this, click Ok. All the classes will then be generated in a file called &lt;i&gt;DataClasses.generated.cs&lt;/i&gt; where &lt;i&gt;DataClasses&lt;/i&gt; is the same as the name of your dbml file.&lt;/li&gt;&lt;/ul&gt;

&lt;h2&gt;Request scoped DataContext&lt;/h2&gt;
The second part of this solution is the request scoped DataContext. This is a pattern that is commonly used with the Hibernate OR mapper as well as elsewhere, and it means that there is only ever one DataContext per Http request which is stored in the HttpContext.Items collection. It is implemented as a protected property of the GenericRepository class as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
        protected static TDataContext DataContext
        {
            get
            {
                //We are in a web app, use a request scope
                if (HttpContext.Current != null)
                {
                    TDataContext dataContext = (TDataContext)HttpContext.Current.Items[DataContextKey];
                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        HttpContext.Current.Items.Add(DataContextKey, dataContext);
                    }
                    return dataContext;
                }
                else
                {

                    // Creates a Thread Scoped DataContext object that can be reused. 
                    // The DataContext is stored in Thread local storage.
                    // See here http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=361
                    //for a discussion of this code.

                    LocalDataStoreSlot threadData = Thread.GetNamedDataSlot(DataContextKey);
                    object dataContext = null;

                    if (threadData != null)
                        dataContext = Thread.GetData(threadData);

                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        if(threadData == null)
                            threadData = Thread.AllocateNamedDataSlot(DataContextKey);

                        Thread.SetData(threadData, dataContext);
                    }
                    return (TDataContext) dataContext;
                }

            }
        }
&lt;/pre&gt;&lt;br /&gt;As you can see from the code above it handles being used outside a web app by storing the DataContext in a named data slot on the thread it is running in.&lt;br /&gt;&lt;br /&gt;The usefulness of this approach can be seen if you consider a page which uses a number of ObjectDataSources; if we configure our ObjectDataSource to use the DataContext directly then each one will create and dispose of a new DataContext this will not only quickly become a performance overhead, but will also present us with a problem when specifying LoadOptions for the DataContext resulting in more complex, less maintainable code or quite possibly code which doesn't specify loading options at all.&lt;br /&gt;&lt;br /&gt;It should be noted that this approach means that if I have a CategoryRepository class as well as a ProductRepository class, both of which inherit from GenericRepository, both of these classes will use the same DataContext. In other words the DataContext is shared across the whole request, not just by one class type.&lt;br /&gt;
&lt;h2&gt;Custom ObjectDataSource&lt;/h2&gt;
In order for updates to work correctly with databinding it is advisable to use the GenericObjectDataSource control which is included in the DataLayer project. An ordinary ObjectDataSource control will create a new object before doing updates and if there are any unbound properties on this object, they will be left with their default values which will then be saved to the database, the GenericObjectDataSource control gets round this by retrieving the original values from the database, before updating them. For more discussions of the details behind this, see &lt;a href="https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488" class="externalLink"&gt;https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;Submitting changes&lt;/h2&gt;
Another feature of the Linq to Sql architecture is the way that changes are only submitted to the database when the SubmitChanges() method is called on the DataContext. This means that we must either decide at which point to call SubmitChanges() or delegate this responsibility to client code.&lt;br /&gt;To make the classes as flexible as possible any operations which require a call to SubmitChanges (Insert, Update and Delete), are provided with a boolean parameter which specify whether to submit changes immediately or not. There is also an overload of these methods without this parameter which is equivalent to passing true (again this makes use of ObjectDatasources much more straightforward).&lt;br /&gt;The SubmitChanges method of the DataContext is also exposed through the repository class to give Client code the ability to call this explicitly.&lt;br /&gt;
&lt;h2&gt;Sorting and Paging with GridViews&lt;/h2&gt;
There are a number of methods on the GenericRepository class to automatically support paging and sorting in GridViews.&lt;br /&gt;These are:&lt;br /&gt;&lt;pre&gt;
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(int maximumRows, int startRowIndex)
        {
            ...
        }
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression)
        {
         ...
        }
     
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression, int maximumRows, int startRowIndex)
        {
            ...
        }
        public static int Count()
        {
            ...
        }
&lt;/pre&gt;&lt;br /&gt;To use this functionality all you need to do is turn it on in the ObjectDataSource and GridView with the following attributes:&lt;br /&gt;ObjectDataSource: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
EnablePaging=&amp;quot;true&amp;quot; SelectCountMethod=&amp;quot;Count&amp;quot; SortParameterName=&amp;quot;sortExpression&amp;quot;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Gridview:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
AllowPaging=&amp;quot;true&amp;quot; AllowSorting=&amp;quot;true&amp;quot;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And hey presto it just works! This makes it really easy to create sortable, pagable GridViews with no extra coding.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;This release also includes some code from Scott Gu's blog to support Dynamic Querying, see &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx" class="externalLink"&gt;http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; for more details&lt;/i&gt;&lt;br /&gt;
&lt;h2&gt;Logging&lt;/h2&gt;
The code includes an easy way to configure Linq to Sql's logging feature (DataContext.Log) to write to either a text file or the System.Diagnostics.Debugger class which then appears in the output window within Visual Studio.&lt;br /&gt;&lt;br /&gt;To use this functionality you need to add the following lines into your web.config:&lt;br /&gt;&lt;br /&gt;In the &amp;lt;configSections&amp;gt; element:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
&amp;lt;section name=&amp;quot;GenericDataSection&amp;quot; type=&amp;quot;DataLayer.GenericDataSection, DataLayer&amp;quot; allowDefinition=&amp;quot;MachineToApplication&amp;quot; restartOnExternalChanges=&amp;quot;true&amp;quot; requirePermission=&amp;quot;false&amp;quot;/&amp;gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then directly after &amp;lt;configSections&amp;gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
&amp;lt;GenericDataSection LogType=&amp;quot;file&amp;quot; LogFile=&amp;quot;C:\Projects\MultiTierLinqToSql_release\test.txt&amp;quot; DeleteExistingFile=&amp;quot;true&amp;quot;/&amp;gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The first of these lines just declares the second line which is the one that contains the interesting stuff.&lt;br /&gt;There are 3 config options in this section:
&lt;ol&gt;&lt;li&gt;LogType - this can be either 'file' (logs output to a file), 'debug' (logs output to Systems.Diagnostics.Debug) or 'none' (switches logging off). &lt;/li&gt;
&lt;li&gt;LogFile - only applies when LogType is set to 'file', and the default is 'log.txt' it specifies the name of the file to use for logging.&lt;/li&gt;
&lt;li&gt;DeleteExistingFile - only applies when LogType is set to 'file', values can be 'true' or 'false', and the default is true. When this is set to true the file will be overwritten every time a new DataContext is created, effectively once per request. If set to false then all output is appended to the end of the file. This can result in a very large log files so be careful.&lt;/li&gt;&lt;/ol&gt;
&lt;h4&gt;Notes&lt;/h4&gt;
As with all file logging this can be pretty detrimental to performance and so should not be left on in production.&lt;br /&gt;&lt;br /&gt;To handle the logging to the output window I have used the DebuggerWriter class described here: &lt;a href="http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11" class="externalLink"&gt;http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;Error Handling&lt;/h2&gt;
Best practice for managing business rules relating to data integrity with Linq to Sql is to include these rules in partial methods in the entity classes and throw exceptions when they are violated (see http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx for more details).&lt;br /&gt;When using this strategy with an ObjectDataSource, you can then catch these exceptions in the OnUpdated or OnInserted events of your ObjectDataSource and present the information to the user. &lt;br /&gt;To do so you set the OnUpdated and/or the OnInserted attribute of your GenericObjectDatasource:&lt;br /&gt;&lt;pre&gt;
OnUpdated=&amp;quot;ProductDataSource_Updated&amp;quot;
OnInserted=&amp;quot;ProductDataSource_Updated&amp;quot;
&lt;/pre&gt;&lt;br /&gt;and then handle this event in your code behind:&lt;br /&gt;&lt;pre&gt;
protected void ProductDataSource_Updated(object sender, ObjectDataSourceStatusEventArgs e)
    {
        if (e.Exception != null)
        {
            //litError is a literal control which I want to use to display the error to the user
            litError.Text = e.Exception.Message;
            //This tells the objectDataSource that I have handled the error and not to throw it
            e.ExceptionHandled = true;
        }
    }
&lt;/pre&gt;&lt;br /&gt;There is an example of this in the Default.aspx page in the test website.&lt;br /&gt;
&lt;h2&gt;DataLoadOptions&lt;/h2&gt;
As has been widely noted, the way that Linq to Sql works, means that the DataLoadOptions for your DataContext need to be set &lt;i&gt;before&lt;/i&gt; any operations are carried out, and cannot subsequently be changed. This means that in my Asp.Net application I will need to set the DataLoadOptions for the whole request somewhere near the start (assuming of course that I need to set DataLoadOptions at all). It also means that my UI or business layer will need to take responsibility for this. &lt;br /&gt;&lt;br /&gt;What this means in practice is that in a classic Web forms type app I will probably set the DataLoadOptions in the OnInit event of my page, if I'm using MVC then my controller will do it. &lt;br /&gt;
&lt;h2&gt;The code&lt;/h2&gt;
The code consists of 4 projects; GenericDataLayer, which contains the reusable code and 3 demo/test projects
&lt;h3&gt;GenericDataLayer&lt;/h3&gt;
This project contains all of the code you need to use this solution, it can be compiled and referenced in your projects or run as a project within your solutions.&lt;br /&gt;It is made up of:
&lt;ul&gt;&lt;li&gt;GenericRepository class - the main class which implements the generic CRUD methods as discussed above&lt;/li&gt;
&lt;li&gt;GenericObjectDataSource - the custom ObjectDataSource to use in your aspx pages as discussed above. This control also uses the classes GenericObjectDataSourceView and ExposedSr&lt;/li&gt;
&lt;li&gt;FileLogger and DebuggerWriter - classes for logging to text files and System.Debug.Out, see Logging section&lt;/li&gt;
&lt;li&gt;GenericDataSection - a class to handle configuration data&lt;/li&gt;
&lt;li&gt;Dynamic - some code to help in the sorting methods &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;NorthWindDataLayer&lt;/h3&gt;
This project is an example of how to use the code with your database (using Microsoft's NorthWind database), it references the GenericRepository project and contains all the project specific database classes that your application needs to work with. These are:
&lt;ul&gt;&lt;li&gt;Linq to Sql dbml file - In this case pointing to the NorthWind database&lt;/li&gt;
&lt;li&gt;Partial Entity classes which implements a custom data validation rules (see section on Error Handling) - In this project there is just one class Product which implements one rule &lt;/li&gt;
&lt;li&gt;Concrete Repository classes which inherit from GenericRepository and implement custom data access code for specific database entities - This project has two, ProductRepository and CategoryRepository &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;A test web project&lt;/h3&gt;
This project has one page with a GridView and a FormView which use the data layer via GenericObjectDataSources to list all the products in the Northwind database, allow editing and deletion of those projects, and insert new products via the FormView. &lt;br /&gt;
&lt;h3&gt;A console app&lt;/h3&gt;
To test functionality outside the context of a web application &lt;br /&gt;&lt;br /&gt;To run the example project:
&lt;ul&gt;&lt;li&gt;Download and unzip the release &lt;/li&gt;
&lt;li&gt;Open the solution in VS2008&lt;/li&gt;
&lt;li&gt;Change the connection string in the web.config to point to a Northwind database&lt;/li&gt;
&lt;li&gt;Run the web project&lt;/li&gt;&lt;/ul&gt;
&lt;br /&gt;To use the code in your own projects
&lt;ul&gt;&lt;li&gt;Create a class library to contain your Linq to Sql classes, partial entities and concrete repositories&lt;/li&gt;
&lt;li&gt;Reference the GenericDataLayer project (either compiled or within your solution)&lt;/li&gt;
&lt;li&gt;Create one entity repository class for each Linq to Sql entity, inheriting from Genericrepository&lt;/li&gt;
&lt;li&gt;Optionally define any new entity specific data access operations in your entity repository classes&lt;/li&gt;
&lt;li&gt;Make use of the GenericObjectDataSource to get easy inserts, updates, deletes, sorting and paging&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;</description><author>rbates</author><pubDate>Tue, 14 Apr 2009 11:52:53 GMT</pubDate><guid isPermaLink="false">Updated Wiki: Home 20090414115253A</guid></item><item><title>Updated Wiki: Home</title><link>http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=Home&amp;version=17</link><description>&lt;div class="wikidoc"&gt;&lt;h1&gt;Multi tier architecture for Linq to Sql&lt;/h1&gt;
&lt;i&gt;I am still updating this, nothing in here is wrong, but it may be incomplete - Rupert&lt;/i&gt;&lt;br /&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
This resource shows an approach for using Linq to Sql within a multi tier Asp.Net application, and particularly how it can be made to work well with ObjectDataSources. It is here as a discussion piece as well as a usable bit of code.&lt;br /&gt;&lt;br /&gt;The key features are a Request-scoped datacontext and entity repository classes which provide easy to use Create, Retrieve, Update and Delete (CRUD) operations implemented with Generics. Also included is a T4 template for auto generation of repositories from a dbml file. &lt;br /&gt;
&lt;h2&gt;Entity Repository classes&lt;/h2&gt;
Each database entity has an associated repository class which is used to perform common CRUD operations. Specific entity repositorys inherit from a generic class &lt;i&gt;GenericRepository&lt;/i&gt; which already implements all the basic Select, Insert, Update &amp;amp; Delete operations.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
[System.ComponentModel.DataObject]
public class GenericRepository&amp;lt;TEntity, TDataContext&amp;gt; where TDataContext : DataContext
{
    public static List&amp;lt;TEntity&amp;gt; SelectAll()
    {
          ...
    }
    public static void Insert(TEntity entity)
    {
        ...
    }
    public static void Update(TEntity entity)
    {
        ...
    }
    public static void Delete(TEntity entity)
    {
        ...
    }
}
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Specific repositories then inherit from this by specifying the entity type which they are concerned with as well as the type of the DataContext used, as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;//ProductRepository class
public class ProductRepository : GenericRepository&amp;lt;Product, NorthwindDataContext&amp;gt;
{
}
&lt;/pre&gt;&lt;br /&gt;which allows client code such as the following:&lt;br /&gt;&lt;pre&gt;
   var productRepository = new ProductRepository();
   IList&amp;lt;Product&amp;gt; products = productRepository.SelectAll();
&lt;/pre&gt;&lt;br /&gt;The use of Generics means that I don't need to add any code at all into my ProductRepository to get all the standard CRUD operations in a fully type safe way. My ProductRepository class can now be customised to add any further data access methods which are specific to Products, for instance GetByCategoryId().&lt;br /&gt;There is also a class GenericStaticRepository which allows you to use this functionality in a static way so in the example above, rather than instantiating a ProductRepository I could simply do this:&lt;br /&gt;&lt;pre&gt;
   IList&amp;lt;Product&amp;gt; products = ProductStaticRepository.SelectAll();
&lt;/pre&gt;&lt;br /&gt;All of these concrete classes are auto generated by the T4 template included with the project as described below.&lt;br /&gt;
&lt;h2&gt;T4 Template&lt;/h2&gt;
Included in the source code is a &lt;a href="http://www.google.co.uk/search?hl=en&amp;amp;q=t4+templates&amp;amp;btnG=Google+Search&amp;amp;meta=&amp;amp;aq=0&amp;amp;oq=t4+tem" class="externalLink"&gt;T4 template&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; which will generate entities and concrete repositories (both static and non-static) with interfaces to facilitate testing. To use it you need to do the following:
&lt;ul&gt;&lt;li&gt;copy the files DataClasses.tt and L2ST4.ttinclude from the T4Templates directory into your project specific datalayer project&lt;/li&gt;
&lt;li&gt;ensure that DataClasses.tt has the same name as the dbml file (so in the example Northwind project DataClasses.tt has been renamed to Northwind.tt to match Northwind.dbml)&lt;/li&gt;
&lt;li&gt;to generate the classes, open DataClasses.tt (or whatever it is now called) and save it. You will probably get a dialog box asking if you are sure you  want to do this, click Ok. All the classes will then be generated in a file called &lt;i&gt;DataClasses.generated.cs&lt;/i&gt; where &lt;i&gt;DataClasses&lt;/i&gt; is the same as the name of your dbml file.&lt;/li&gt;&lt;/ul&gt;

&lt;h2&gt;Request scoped DataContext&lt;/h2&gt;
The second part of this solution is the request scoped DataContext. This is a pattern that is commonly used with the Hibernate OR mapper as well as elsewhere, and it means that there is only ever one DataContext per Http request which is stored in the HttpContext.Items collection. It is implemented as a protected property of the GenericRepository class as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
        protected static TDataContext DataContext
        {
            get
            {
                //We are in a web app, use a request scope
                if (HttpContext.Current != null)
                {
                    TDataContext dataContext = (TDataContext)HttpContext.Current.Items[DataContextKey];
                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        HttpContext.Current.Items.Add(DataContextKey, dataContext);
                    }
                    return dataContext;
                }
                else
                {

                    // Creates a Thread Scoped DataContext object that can be reused. 
                    // The DataContext is stored in Thread local storage.
                    // See here http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=361
                    //for a discussion of this code.

                    LocalDataStoreSlot threadData = Thread.GetNamedDataSlot(DataContextKey);
                    object dataContext = null;

                    if (threadData != null)
                        dataContext = Thread.GetData(threadData);

                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        if(threadData == null)
                            threadData = Thread.AllocateNamedDataSlot(DataContextKey);

                        Thread.SetData(threadData, dataContext);
                    }
                    return (TDataContext) dataContext;
                }

            }
        }
&lt;/pre&gt;&lt;br /&gt;As you can see from the code above it handles being used outside a web app by storing the DataContext in a named data slot on the thread it is running in.&lt;br /&gt;&lt;br /&gt;The usefulness of this approach can be seen if you consider a page which uses a number of ObjectDataSources; if we configure our ObjectDataSource to use the DataContext directly then each one will create and dispose of a new DataContext this will not only quickly become a performance overhead, but will also present us with a problem when specifying LoadOptions for the DataContext resulting in more complex, less maintainable code or quite possibly code which doesn't specify loading options at all.&lt;br /&gt;&lt;br /&gt;It should be noted that this approach means that if I have a CategoryRepository class as well as a ProductRepository class, both of which inherit from GenericRepository, both of these classes will use the same DataContext. In other words the DataContext is shared across the whole request, not just by one class type.&lt;br /&gt;
&lt;h2&gt;Custom ObjectDataSource&lt;/h2&gt;
In order for updates to work correctly with databinding it is advisable to use the GenericObjectDataSource control which is included in the DataLayer project. An ordinary ObjectDataSource control will create a new object before doing updates and if there are any unbound properties on this object, they will be left with their default values which will then be saved to the database, the GenericObjectDataSource control gets round this by retrieving the original values from the database, before updating them. For more discussions of the details behind this, see &lt;a href="https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488" class="externalLink"&gt;https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;Submitting changes&lt;/h2&gt;
Another feature of the Linq to Sql architecture is the way that changes are only submitted to the database when the SubmitChanges() method is called on the DataContext. This means that we must either decide at which point to call SubmitChanges() or delegate this responsibility to client code.&lt;br /&gt;To make the classes as flexible as possible any operations which require a call to SubmitChanges (Insert, Update and Delete), are provided with a boolean parameter which specify whether to submit changes immediately or not. There is also an overload of these methods without this parameter which is equivalent to passing true (again this makes use of ObjectDatasources much more straightforward).&lt;br /&gt;The SubmitChanges method of the DataContext is also exposed through the repository class to give Client code the ability to call this explicitly.&lt;br /&gt;
&lt;h2&gt;Sorting and Paging with GridViews&lt;/h2&gt;
There are a number of methods on the GenericRepository class to automatically support paging and sorting in GridViews.&lt;br /&gt;These are:&lt;br /&gt;&lt;pre&gt;
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(int maximumRows, int startRowIndex)
        {
            ...
        }
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression)
        {
         ...
        }
     
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression, int maximumRows, int startRowIndex)
        {
            ...
        }
        public static int Count()
        {
            ...
        }
&lt;/pre&gt;&lt;br /&gt;To use this functionality all you need to do is turn it on in the ObjectDataSource and GridView with the following attributes:&lt;br /&gt;ObjectDataSource: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
EnablePaging=&amp;quot;true&amp;quot; SelectCountMethod=&amp;quot;Count&amp;quot; SortParameterName=&amp;quot;sortExpression&amp;quot;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Gridview:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
AllowPaging=&amp;quot;true&amp;quot; AllowSorting=&amp;quot;true&amp;quot;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And hey presto it just works! This makes it really easy to create sortable, pagable GridViews with no extra coding.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;This release also includes some code from Scott Gu's blog to support Dynamic Querying, see &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx" class="externalLink"&gt;http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; for more details&lt;/i&gt;&lt;br /&gt;
&lt;h2&gt;Logging&lt;/h2&gt;
The code includes an easy way to configure Linq to Sql's logging feature (DataContext.Log) to write to either a text file or the System.Diagnostics.Debugger class which then appears in the output window within Visual Studio.&lt;br /&gt;&lt;br /&gt;To use this functionality you need to add the following lines into your web.config:&lt;br /&gt;&lt;br /&gt;In the &amp;lt;configSections&amp;gt; element:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
&amp;lt;section name=&amp;quot;GenericDataSection&amp;quot; type=&amp;quot;DataLayer.GenericDataSection, DataLayer&amp;quot; allowDefinition=&amp;quot;MachineToApplication&amp;quot; restartOnExternalChanges=&amp;quot;true&amp;quot; requirePermission=&amp;quot;false&amp;quot;/&amp;gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then directly after &amp;lt;configSections&amp;gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
&amp;lt;GenericDataSection LogType=&amp;quot;file&amp;quot; LogFile=&amp;quot;C:\Projects\MultiTierLinqToSql_release\test.txt&amp;quot; DeleteExistingFile=&amp;quot;true&amp;quot;/&amp;gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The first of these lines just declares the second line which is the one that contains the interesting stuff.&lt;br /&gt;There are 3 config options in this section:
&lt;ol&gt;&lt;li&gt;LogType - this can be either 'file' (logs output to a file), 'debug' (logs output to Systems.Diagnostics.Debug) or 'none' (switches logging off). &lt;/li&gt;
&lt;li&gt;LogFile - only applies when LogType is set to 'file', and the default is 'log.txt' it specifies the name of the file to use for logging.&lt;/li&gt;
&lt;li&gt;DeleteExistingFile - only applies when LogType is set to 'file', values can be 'true' or 'false', and the default is true. When this is set to true the file will be overwritten every time a new DataContext is created, effectively once per request. If set to false then all output is appended to the end of the file. This can result in a very large log files so be careful.&lt;/li&gt;&lt;/ol&gt;
&lt;h4&gt;Notes&lt;/h4&gt;
As with all file logging this can be pretty detrimental to performance and so should not be left on in production.&lt;br /&gt;&lt;br /&gt;To handle the logging to the output window I have used the DebuggerWriter class described here: &lt;a href="http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11" class="externalLink"&gt;http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;Error Handling&lt;/h2&gt;
Best practice for managing business rules relating to data integrity with Linq to Sql is to include these rules in partial methods in the entity classes and throw exceptions when they are violated (see http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx for more details).&lt;br /&gt;When using this strategy with an ObjectDataSource, you can then catch these exceptions in the OnUpdated or OnInserted events of your ObjectDataSource and present the information to the user. &lt;br /&gt;To do so you set the OnUpdated and/or the OnInserted attribute of your GenericObjectDatasource:&lt;br /&gt;&lt;pre&gt;
OnUpdated=&amp;quot;ProductDataSource_Updated&amp;quot;
OnInserted=&amp;quot;ProductDataSource_Updated&amp;quot;
&lt;/pre&gt;&lt;br /&gt;and then handle this event in your code behind:&lt;br /&gt;&lt;pre&gt;
protected void ProductDataSource_Updated(object sender, ObjectDataSourceStatusEventArgs e)
    {
        if (e.Exception != null)
        {
            //litError is a literal control which I want to use to display the error to the user
            litError.Text = e.Exception.Message;
            //This tells the objectDataSource that I have handled the error and not to throw it
            e.ExceptionHandled = true;
        }
    }
&lt;/pre&gt;&lt;br /&gt;There is an example of this in the Default.aspx page in the test website.&lt;br /&gt;
&lt;h2&gt;DataLoadOptions&lt;/h2&gt;
As has been widely noted, the way that Linq to Sql works, means that the DataLoadOptions for your DataContext need to be set &lt;i&gt;before&lt;/i&gt; any operations are carried out, and cannot subsequently be changed. This means that in my Asp.Net application I will need to set the DataLoadOptions for the whole request somewhere near the start (assuming of course that I need to set DataLoadOptions at all). It also means that my UI or business layer will need to take responsibility for this. &lt;br /&gt;&lt;br /&gt;What this means in practice is that in a classic Web forms type app I will probably set the DataLoadOptions in the OnInit event of my page, if I'm using MVC then my controller will do it. &lt;br /&gt;
&lt;h2&gt;The code&lt;/h2&gt;
The code consists of 4 projects; GenericDataLayer, which contains the reusable code and 3 demo/test projects
&lt;h3&gt;GenericDataLayer&lt;/h3&gt;
This project contains all of the code you need to use this solution, it can be compiled and referenced in your projects or run as a project within your solutions.&lt;br /&gt;It is made up of:
&lt;ul&gt;&lt;li&gt;GenericRepository class - the main class which implements the generic CRUD methods as discussed above&lt;/li&gt;
&lt;li&gt;GenericObjectDataSource - the custom ObjectDataSource to use in your aspx pages as discussed above. This control also uses the classes GenericObjectDataSourceView and ExposedSr&lt;/li&gt;
&lt;li&gt;FileLogger and DebuggerWriter - classes for logging to text files and System.Debug.Out, see Logging section&lt;/li&gt;
&lt;li&gt;GenericDataSection - a class to handle configuration data&lt;/li&gt;
&lt;li&gt;Dynamic - some code to help in the sorting methods &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;NorthWindDataLayer&lt;/h3&gt;
This project is an example of how to use the code with your database (using Microsoft's NorthWind database), it references the GenericRepository project and contains all the project specific database classes that your application needs to work with. These are:
&lt;ul&gt;&lt;li&gt;Linq to Sql dbml file - In this case pointing to the NorthWind database&lt;/li&gt;
&lt;li&gt;Partial Entity classes which implements a custom data validation rules (see section on Error Handling) - In this project there is just one class Product which implements one rule &lt;/li&gt;
&lt;li&gt;Concrete Repository classes which inherit from GenericRepository and implement custom data access code for specific database entities - This project has two, ProductRepository and CategoryRepository &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;A test web project&lt;/h3&gt;
This project has one page with a GridView and a FormView which use the data layer via GenericObjectDataSources to list all the products in the Northwind database, allow editing and deletion of those projects, and insert new products via the FormView. &lt;br /&gt;
&lt;h3&gt;A console app&lt;/h3&gt;
To test functionality outside the context of a web application &lt;br /&gt;&lt;br /&gt;To run the example project:
&lt;ul&gt;&lt;li&gt;Download and unzip the release &lt;/li&gt;
&lt;li&gt;Open the solution in VS2008&lt;/li&gt;
&lt;li&gt;Change the connection string in the web.config to point to a Northwind database&lt;/li&gt;
&lt;li&gt;Run the web project&lt;/li&gt;&lt;/ul&gt;
&lt;br /&gt;To use the code in your own projects
&lt;ul&gt;&lt;li&gt;Create a class library to contain your Linq to Sql classes, partial entities and concrete repositories&lt;/li&gt;
&lt;li&gt;Reference the GenericDataLayer project (either compiled or within your solution)&lt;/li&gt;
&lt;li&gt;Create one entity repository class for each Linq to Sql entity, inheriting from Genericrepository&lt;/li&gt;
&lt;li&gt;Optionally define any new entity specific data access operations in your entity repository classes&lt;/li&gt;
&lt;li&gt;Make use of the GenericObjectDataSource to get easy inserts, updates, deletes, sorting and paging&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;</description><author>rbates</author><pubDate>Tue, 14 Apr 2009 11:51:45 GMT</pubDate><guid isPermaLink="false">Updated Wiki: Home 20090414115145A</guid></item><item><title>Updated Wiki: Home</title><link>http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=Home&amp;version=16</link><description>&lt;div class="wikidoc"&gt;&lt;h1&gt;Multi tier architecture for Linq to Sql&lt;/h1&gt;
&lt;i&gt;I am still updating this, nothing in here is wrong, but it may be incomplete - Rupert&lt;/i&gt;&lt;br /&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
This resource shows an approach for using Linq to Sql within a multi tier Asp.Net application, and particularly how it can be made to work well with ObjectDataSources. It is here as a discussion piece as well as a usable bit of code.&lt;br /&gt;&lt;br /&gt;The key features are a Request-scoped datacontext and entity repository classes which provide easy to use Create, Retrieve, Update and Delete (CRUD) operations implemented with Generics. Also included is a T4 template for auto generation of repositories from a dbml file. &lt;br /&gt;
&lt;h2&gt;Entity Repository classes&lt;/h2&gt;
Each database entity has an associated repository class which is used to perform common CRUD operations. Specific entity repositorys inherit from a generic class &lt;i&gt;GenericRepository&lt;/i&gt; which already implements all the basic Select, Insert, Update &amp;amp; Delete operations.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
[System.ComponentModel.DataObject]
public class GenericRepository&amp;lt;TEntity, TDataContext&amp;gt; where TDataContext : DataContext
{
    public static List&amp;lt;TEntity&amp;gt; SelectAll()
    {
          ...
    }
    public static void Insert(TEntity entity)
    {
        ...
    }
    public static void Update(TEntity entity)
    {
        ...
    }
    public static void Delete(TEntity entity)
    {
        ...
    }
}
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Specific repositories then inherit from this by specifying the entity type which they are concerned with as well as the type of the DataContext used, as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;//ProductRepository class
public class ProductRepository : GenericRepository&amp;lt;Product, NorthwindDataContext&amp;gt;
{
}
&lt;/pre&gt;&lt;br /&gt;which allows client code such as the following:&lt;br /&gt;&lt;pre&gt;
   var productRepository = new ProductRepository();
   IList&amp;lt;Product&amp;gt; products = productRepository.SelectAll();
&lt;/pre&gt;&lt;br /&gt;The use of Generics means that I don't need to add any code at all into my ProductRepository to get all the standard CRUD operations in a fully type safe way. My ProductRepository class can now be customised to add any further data access methods which are specific to Products, for instance GetByCategoryId().&lt;br /&gt;There is also a class GenericStaticRepository which allows you to use this functionality in a static way so in the example above, rather than instantiating a ProductRepository I could simply do this:&lt;br /&gt;&lt;pre&gt;
   IList&amp;lt;Product&amp;gt; products = ProductStaticRepository.SelectAll();
&lt;/pre&gt;&lt;br /&gt;All of these concrete classes are auto generated by the T4 template included with the project as described below.&lt;br /&gt;
&lt;h2&gt;T4 Template&lt;/h2&gt;
Included in the source code is a &lt;a href="http:// T4 template : http://www.google.co.uk/search?hl=en&amp;amp;q=t4+templates&amp;amp;btnG=Google+Search&amp;amp;meta=&amp;amp;aq=0&amp;amp;oq=t4+tem" class="externalLink"&gt; T4 template : http://www.google.co.uk/search?hl=en&amp;amp;q=t4+templates&amp;amp;btnG=Google+Search&amp;amp;meta=&amp;amp;aq=0&amp;amp;oq=t4+tem&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; which will generate entities and concrete repositories (both static and non-static) with interfaces to facilitate testing. To use it you need to do the following
&lt;ul&gt;&lt;li&gt;copy the files DataClasses.tt and L2ST4.ttinclude from the T4Templates directory into your project specific datalayer project&lt;/li&gt;
&lt;li&gt;ensure that DataClasses.tt has the same name as the dbml file (so in the example Northwind project DataClasses.tt has been renamed to Northwind.tt to match Northwind.dbml)&lt;/li&gt;
&lt;li&gt;to generate the classes, open DataClasses.tt (or whatever it is now called) and save it. You will probably get a dialog box asking if you are sure you  want to do this, click Ok. All the classes will then be generated in a file called &lt;i&gt;DataClasses.generated.cs&lt;/i&gt; where &lt;i&gt;DataClasses&lt;/i&gt; is the same as the name of your dbml file.&lt;/li&gt;&lt;/ul&gt;

&lt;h2&gt;Request scoped DataContext&lt;/h2&gt;
The second part of this solution is the request scoped DataContext. This is a pattern that is commonly used with the Hibernate OR mapper as well as elsewhere, and it means that there is only ever one DataContext per Http request which is stored in the HttpContext.Items collection. It is implemented as a protected property of the GenericRepository class as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
        protected static TDataContext DataContext
        {
            get
            {
                //We are in a web app, use a request scope
                if (HttpContext.Current != null)
                {
                    TDataContext dataContext = (TDataContext)HttpContext.Current.Items[DataContextKey];
                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        HttpContext.Current.Items.Add(DataContextKey, dataContext);
                    }
                    return dataContext;
                }
                else
                {

                    // Creates a Thread Scoped DataContext object that can be reused. 
                    // The DataContext is stored in Thread local storage.
                    // See here http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=361
                    //for a discussion of this code.

                    LocalDataStoreSlot threadData = Thread.GetNamedDataSlot(DataContextKey);
                    object dataContext = null;

                    if (threadData != null)
                        dataContext = Thread.GetData(threadData);

                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        if(threadData == null)
                            threadData = Thread.AllocateNamedDataSlot(DataContextKey);

                        Thread.SetData(threadData, dataContext);
                    }
                    return (TDataContext) dataContext;
                }

            }
        }
&lt;/pre&gt;&lt;br /&gt;As you can see from the code above it handles being used outside a web app by storing the DataContext in a named data slot on the thread it is running in.&lt;br /&gt;&lt;br /&gt;The usefulness of this approach can be seen if you consider a page which uses a number of ObjectDataSources; if we configure our ObjectDataSource to use the DataContext directly then each one will create and dispose of a new DataContext this will not only quickly become a performance overhead, but will also present us with a problem when specifying LoadOptions for the DataContext resulting in more complex, less maintainable code or quite possibly code which doesn't specify loading options at all.&lt;br /&gt;&lt;br /&gt;It should be noted that this approach means that if I have a CategoryRepository class as well as a ProductRepository class, both of which inherit from GenericRepository, both of these classes will use the same DataContext. In other words the DataContext is shared across the whole request, not just by one class type.&lt;br /&gt;
&lt;h2&gt;Custom ObjectDataSource&lt;/h2&gt;
In order for updates to work correctly with databinding it is advisable to use the GenericObjectDataSource control which is included in the DataLayer project. An ordinary ObjectDataSource control will create a new object before doing updates and if there are any unbound properties on this object, they will be left with their default values which will then be saved to the database, the GenericObjectDataSource control gets round this by retrieving the original values from the database, before updating them. For more discussions of the details behind this, see &lt;a href="https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488" class="externalLink"&gt;https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;Submitting changes&lt;/h2&gt;
Another feature of the Linq to Sql architecture is the way that changes are only submitted to the database when the SubmitChanges() method is called on the DataContext. This means that we must either decide at which point to call SubmitChanges() or delegate this responsibility to client code.&lt;br /&gt;To make the classes as flexible as possible any operations which require a call to SubmitChanges (Insert, Update and Delete), are provided with a boolean parameter which specify whether to submit changes immediately or not. There is also an overload of these methods without this parameter which is equivalent to passing true (again this makes use of ObjectDatasources much more straightforward).&lt;br /&gt;The SubmitChanges method of the DataContext is also exposed through the repository class to give Client code the ability to call this explicitly.&lt;br /&gt;
&lt;h2&gt;Sorting and Paging with GridViews&lt;/h2&gt;
There are a number of methods on the GenericRepository class to automatically support paging and sorting in GridViews.&lt;br /&gt;These are:&lt;br /&gt;&lt;pre&gt;
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(int maximumRows, int startRowIndex)
        {
            ...
        }
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression)
        {
         ...
        }
     
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression, int maximumRows, int startRowIndex)
        {
            ...
        }
        public static int Count()
        {
            ...
        }
&lt;/pre&gt;&lt;br /&gt;To use this functionality all you need to do is turn it on in the ObjectDataSource and GridView with the following attributes:&lt;br /&gt;ObjectDataSource: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
EnablePaging=&amp;quot;true&amp;quot; SelectCountMethod=&amp;quot;Count&amp;quot; SortParameterName=&amp;quot;sortExpression&amp;quot;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Gridview:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
AllowPaging=&amp;quot;true&amp;quot; AllowSorting=&amp;quot;true&amp;quot;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And hey presto it just works! This makes it really easy to create sortable, pagable GridViews with no extra coding.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;This release also includes some code from Scott Gu's blog to support Dynamic Querying, see &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx" class="externalLink"&gt;http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; for more details&lt;/i&gt;&lt;br /&gt;
&lt;h2&gt;Logging&lt;/h2&gt;
The code includes an easy way to configure Linq to Sql's logging feature (DataContext.Log) to write to either a text file or the System.Diagnostics.Debugger class which then appears in the output window within Visual Studio.&lt;br /&gt;&lt;br /&gt;To use this functionality you need to add the following lines into your web.config:&lt;br /&gt;&lt;br /&gt;In the &amp;lt;configSections&amp;gt; element:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
&amp;lt;section name=&amp;quot;GenericDataSection&amp;quot; type=&amp;quot;DataLayer.GenericDataSection, DataLayer&amp;quot; allowDefinition=&amp;quot;MachineToApplication&amp;quot; restartOnExternalChanges=&amp;quot;true&amp;quot; requirePermission=&amp;quot;false&amp;quot;/&amp;gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then directly after &amp;lt;configSections&amp;gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
&amp;lt;GenericDataSection LogType=&amp;quot;file&amp;quot; LogFile=&amp;quot;C:\Projects\MultiTierLinqToSql_release\test.txt&amp;quot; DeleteExistingFile=&amp;quot;true&amp;quot;/&amp;gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The first of these lines just declares the second line which is the one that contains the interesting stuff.&lt;br /&gt;There are 3 config options in this section:
&lt;ol&gt;&lt;li&gt;LogType - this can be either 'file' (logs output to a file), 'debug' (logs output to Systems.Diagnostics.Debug) or 'none' (switches logging off). &lt;/li&gt;
&lt;li&gt;LogFile - only applies when LogType is set to 'file', and the default is 'log.txt' it specifies the name of the file to use for logging.&lt;/li&gt;
&lt;li&gt;DeleteExistingFile - only applies when LogType is set to 'file', values can be 'true' or 'false', and the default is true. When this is set to true the file will be overwritten every time a new DataContext is created, effectively once per request. If set to false then all output is appended to the end of the file. This can result in a very large log files so be careful.&lt;/li&gt;&lt;/ol&gt;
&lt;h4&gt;Notes&lt;/h4&gt;
As with all file logging this can be pretty detrimental to performance and so should not be left on in production.&lt;br /&gt;&lt;br /&gt;To handle the logging to the output window I have used the DebuggerWriter class described here: &lt;a href="http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11" class="externalLink"&gt;http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;Error Handling&lt;/h2&gt;
Best practice for managing business rules relating to data integrity with Linq to Sql is to include these rules in partial methods in the entity classes and throw exceptions when they are violated (see http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx for more details).&lt;br /&gt;When using this strategy with an ObjectDataSource, you can then catch these exceptions in the OnUpdated or OnInserted events of your ObjectDataSource and present the information to the user. &lt;br /&gt;To do so you set the OnUpdated and/or the OnInserted attribute of your GenericObjectDatasource:&lt;br /&gt;&lt;pre&gt;
OnUpdated=&amp;quot;ProductDataSource_Updated&amp;quot;
OnInserted=&amp;quot;ProductDataSource_Updated&amp;quot;
&lt;/pre&gt;&lt;br /&gt;and then handle this event in your code behind:&lt;br /&gt;&lt;pre&gt;
protected void ProductDataSource_Updated(object sender, ObjectDataSourceStatusEventArgs e)
    {
        if (e.Exception != null)
        {
            //litError is a literal control which I want to use to display the error to the user
            litError.Text = e.Exception.Message;
            //This tells the objectDataSource that I have handled the error and not to throw it
            e.ExceptionHandled = true;
        }
    }
&lt;/pre&gt;&lt;br /&gt;There is an example of this in the Default.aspx page in the test website.&lt;br /&gt;
&lt;h2&gt;DataLoadOptions&lt;/h2&gt;
As has been widely noted, the way that Linq to Sql works, means that the DataLoadOptions for your DataContext need to be set &lt;i&gt;before&lt;/i&gt; any operations are carried out, and cannot subsequently be changed. This means that in my Asp.Net application I will need to set the DataLoadOptions for the whole request somewhere near the start (assuming of course that I need to set DataLoadOptions at all). It also means that my UI or business layer will need to take responsibility for this. &lt;br /&gt;&lt;br /&gt;What this means in practice is that in a classic Web forms type app I will probably set the DataLoadOptions in the OnInit event of my page, if I'm using MVC then my controller will do it. &lt;br /&gt;
&lt;h2&gt;The code&lt;/h2&gt;
The code consists of 4 projects; GenericDataLayer, which contains the reusable code and 3 demo/test projects
&lt;h3&gt;GenericDataLayer&lt;/h3&gt;
This project contains all of the code you need to use this solution, it can be compiled and referenced in your projects or run as a project within your solutions.&lt;br /&gt;It is made up of:
&lt;ul&gt;&lt;li&gt;GenericRepository class - the main class which implements the generic CRUD methods as discussed above&lt;/li&gt;
&lt;li&gt;GenericObjectDataSource - the custom ObjectDataSource to use in your aspx pages as discussed above. This control also uses the classes GenericObjectDataSourceView and ExposedSr&lt;/li&gt;
&lt;li&gt;FileLogger and DebuggerWriter - classes for logging to text files and System.Debug.Out, see Logging section&lt;/li&gt;
&lt;li&gt;GenericDataSection - a class to handle configuration data&lt;/li&gt;
&lt;li&gt;Dynamic - some code to help in the sorting methods &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;NorthWindDataLayer&lt;/h3&gt;
This project is an example of how to use the code with your database (using Microsoft's NorthWind database), it references the GenericRepository project and contains all the project specific database classes that your application needs to work with. These are:
&lt;ul&gt;&lt;li&gt;Linq to Sql dbml file - In this case pointing to the NorthWind database&lt;/li&gt;
&lt;li&gt;Partial Entity classes which implements a custom data validation rules (see section on Error Handling) - In this project there is just one class Product which implements one rule &lt;/li&gt;
&lt;li&gt;Concrete Repository classes which inherit from GenericRepository and implement custom data access code for specific database entities - This project has two, ProductRepository and CategoryRepository &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;A test web project&lt;/h3&gt;
This project has one page with a GridView and a FormView which use the data layer via GenericObjectDataSources to list all the products in the Northwind database, allow editing and deletion of those projects, and insert new products via the FormView. &lt;br /&gt;
&lt;h3&gt;A console app&lt;/h3&gt;
To test functionality outside the context of a web application &lt;br /&gt;&lt;br /&gt;To run the example project:
&lt;ul&gt;&lt;li&gt;Download and unzip the release &lt;/li&gt;
&lt;li&gt;Open the solution in VS2008&lt;/li&gt;
&lt;li&gt;Change the connection string in the web.config to point to a Northwind database&lt;/li&gt;
&lt;li&gt;Run the web project&lt;/li&gt;&lt;/ul&gt;
&lt;br /&gt;To use the code in your own projects
&lt;ul&gt;&lt;li&gt;Create a class library to contain your Linq to Sql classes, partial entities and concrete repositories&lt;/li&gt;
&lt;li&gt;Reference the GenericDataLayer project (either compiled or within your solution)&lt;/li&gt;
&lt;li&gt;Create one entity repository class for each Linq to Sql entity, inheriting from Genericrepository&lt;/li&gt;
&lt;li&gt;Optionally define any new entity specific data access operations in your entity repository classes&lt;/li&gt;
&lt;li&gt;Make use of the GenericObjectDataSource to get easy inserts, updates, deletes, sorting and paging&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;</description><author>rbates</author><pubDate>Tue, 14 Apr 2009 11:50:07 GMT</pubDate><guid isPermaLink="false">Updated Wiki: Home 20090414115007A</guid></item><item><title>Updated Wiki: Home</title><link>http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=Home&amp;version=15</link><description>&lt;div class="wikidoc"&gt;&lt;h1&gt;Multi tier architecture for Linq to Sql&lt;/h1&gt;
&lt;i&gt;I am still updating this, nothing in here is wrong, but it may be incomplete - Rupert&lt;/i&gt;&lt;br /&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
This resource shows an approach for using Linq to Sql within a multi tier Asp.Net application, and particularly how it can be made to work well with ObjectDataSources. It is here as a discussion piece as well as a usable bit of code.&lt;br /&gt;&lt;br /&gt;The key features are a Request-scoped datacontext and entity repository classes which provide easy to use Create, Retrieve, Update and Delete (CRUD) operations implemented with Generics. Also included is a T4 template for auto generation of repositories from a dbml file. &lt;br /&gt;
&lt;h2&gt;Entity Repository classes&lt;/h2&gt;
Each database entity has an associated repository class which is used to perform common CRUD operations. Specific entity repositorys inherit from a generic class &lt;i&gt;GenericRepository&lt;/i&gt; which already implements all the basic Select, Insert, Update &amp;amp; Delete operations.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
[System.ComponentModel.DataObject]
public class GenericRepository&amp;lt;TEntity, TDataContext&amp;gt; where TDataContext : DataContext
{
    public static List&amp;lt;TEntity&amp;gt; SelectAll()
    {
          ...
    }
    public static void Insert(TEntity entity)
    {
        ...
    }
    public static void Update(TEntity entity)
    {
        ...
    }
    public static void Delete(TEntity entity)
    {
        ...
    }
}
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Specific repositories then inherit from this by specifying the entity type which they are concerned with as well as the type of the DataContext used, as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;//ProductRepository class
public class ProductRepository : GenericRepository&amp;lt;Product, NorthwindDataContext&amp;gt;
{
}
&lt;/pre&gt;&lt;br /&gt;which allows client code such as the following:&lt;br /&gt;&lt;pre&gt;
   var productRepository = new ProductRepository();
   IList&amp;lt;Product&amp;gt; products = productRepository.SelectAll();
&lt;/pre&gt;&lt;br /&gt;The use of Generics means that I don't need to add any code at all into my ProductRepository to get all the standard CRUD operations in a fully type safe way. My ProductRepository class can now be customised to add any further data access methods which are specific to Products, for instance GetByCategoryId().&lt;br /&gt;There is also a class GenericStaticRepository which allows you to use this functionality in a static way so in the example above, rather than instantiating a ProductRepository I could simply do this:&lt;br /&gt;&lt;pre&gt;
   IList&amp;lt;Product&amp;gt; products = ProductStaticRepository.SelectAll();
&lt;/pre&gt;&lt;br /&gt;All of these concrete classes are generated for my by the T4 template included with the project.&lt;br /&gt;
&lt;h2&gt;Request scoped DataContext&lt;/h2&gt;
The second part of this solution is the request scoped DataContext. This is a pattern that is commonly used with the Hibernate OR mapper as well as elsewhere, and it means that there is only ever one DataContext per Http request which is stored in the HttpContext.Items collection. It is implemented as a protected property of the GenericRepository class as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
        protected static TDataContext DataContext
        {
            get
            {
                //We are in a web app, use a request scope
                if (HttpContext.Current != null)
                {
                    TDataContext dataContext = (TDataContext)HttpContext.Current.Items[DataContextKey];
                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        HttpContext.Current.Items.Add(DataContextKey, dataContext);
                    }
                    return dataContext;
                }
                else
                {

                    // Creates a Thread Scoped DataContext object that can be reused. 
                    // The DataContext is stored in Thread local storage.
                    // See here http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=361
                    //for a discussion of this code.

                    LocalDataStoreSlot threadData = Thread.GetNamedDataSlot(DataContextKey);
                    object dataContext = null;

                    if (threadData != null)
                        dataContext = Thread.GetData(threadData);

                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        if(threadData == null)
                            threadData = Thread.AllocateNamedDataSlot(DataContextKey);

                        Thread.SetData(threadData, dataContext);
                    }
                    return (TDataContext) dataContext;
                }

            }
        }
&lt;/pre&gt;&lt;br /&gt;As you can see from the code above it handles being used outside a web app by storing the DataContext in a named data slot on the thread it is running in.&lt;br /&gt;&lt;br /&gt;The usefulness of this approach can be seen if you consider a page which uses a number of ObjectDataSources; if we configure our ObjectDataSource to use the DataContext directly then each one will create and dispose of a new DataContext this will not only quickly become a performance overhead, but will also present us with a problem when specifying LoadOptions for the DataContext resulting in more complex, less maintainable code or quite possibly code which doesn't specify loading options at all.&lt;br /&gt;&lt;br /&gt;It should be noted that this approach means that if I have a CategoryRepository class as well as a ProductRepository class, both of which inherit from GenericRepository, both of these classes will use the same DataContext. In other words the DataContext is shared across the whole request, not just by one class type.&lt;br /&gt;
&lt;h2&gt;Custom ObjectDataSource&lt;/h2&gt;
In order for updates to work correctly with databinding it is advisable to use the GenericObjectDataSource control which is included in the DataLayer project. An ordinary ObjectDataSource control will create a new object before doing updates and if there are any unbound properties on this object, they will be left with their default values which will then be saved to the database, the GenericObjectDataSource control gets round this by retrieving the original values from the database, before updating them. For more discussions of the details behind this, see &lt;a href="https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488" class="externalLink"&gt;https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;Submitting changes&lt;/h2&gt;
Another feature of the Linq to Sql architecture is the way that changes are only submitted to the database when the SubmitChanges() method is called on the DataContext. This means that we must either decide at which point to call SubmitChanges() or delegate this responsibility to client code.&lt;br /&gt;To make the classes as flexible as possible any operations which require a call to SubmitChanges (Insert, Update and Delete), are provided with a boolean parameter which specify whether to submit changes immediately or not. There is also an overload of these methods without this parameter which is equivalent to passing true (again this makes use of ObjectDatasources much more straightforward).&lt;br /&gt;The SubmitChanges method of the DataContext is also exposed through the repository class to give Client code the ability to call this explicitly.&lt;br /&gt;
&lt;h2&gt;Sorting and Paging with GridViews&lt;/h2&gt;
There are a number of methods on the GenericRepository class to automatically support paging and sorting in GridViews.&lt;br /&gt;These are:&lt;br /&gt;&lt;pre&gt;
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(int maximumRows, int startRowIndex)
        {
            ...
        }
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression)
        {
         ...
        }
     
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression, int maximumRows, int startRowIndex)
        {
            ...
        }
        public static int Count()
        {
            ...
        }
&lt;/pre&gt;&lt;br /&gt;To use this functionality all you need to do is turn it on in the ObjectDataSource and GridView with the following attributes:&lt;br /&gt;ObjectDataSource: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
EnablePaging=&amp;quot;true&amp;quot; SelectCountMethod=&amp;quot;Count&amp;quot; SortParameterName=&amp;quot;sortExpression&amp;quot;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Gridview:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
AllowPaging=&amp;quot;true&amp;quot; AllowSorting=&amp;quot;true&amp;quot;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And hey presto it just works! This makes it really easy to create sortable, pagable GridViews with no extra coding.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;This release also includes some code from Scott Gu's blog to support Dynamic Querying, see &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx" class="externalLink"&gt;http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; for more details&lt;/i&gt;&lt;br /&gt;
&lt;h2&gt;T4 Template&lt;/h2&gt;
Included in the source code is a &lt;a href="http:// T4 template : http://www.google.co.uk/search?hl=en&amp;amp;q=t4+templates&amp;amp;btnG=Google+Search&amp;amp;meta=&amp;amp;aq=0&amp;amp;oq=t4+tem" class="externalLink"&gt; T4 template : http://www.google.co.uk/search?hl=en&amp;amp;q=t4+templates&amp;amp;btnG=Google+Search&amp;amp;meta=&amp;amp;aq=0&amp;amp;oq=t4+tem&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; which will generate entities and concrete repositories (both static and non-static) with interfaces to facilitate testing. To use it you need to do the following
&lt;ul&gt;&lt;li&gt;copy the files DataClasses.tt and L2ST4.ttinclude from the T4Templates directory into your project specific datalayer project&lt;/li&gt;
&lt;li&gt;ensure that DataClasses.tt has the same name as the dbml file (so in the example Northwind project DataClasses.tt has been renamed to Northwind.tt to match Northwind.dbml)&lt;/li&gt;
&lt;li&gt;to generate the classes, open DataClasses.tt (or whatever it is now called) and save it. You will probably get a dialog box asking if you are sure you  want to do this, click Ok. All the classes will then be generated in a file called &lt;i&gt;DataClasses.generated.cs&lt;/i&gt; where &lt;i&gt;DataClasses&lt;/i&gt; is the same as the name of your dbml file.&lt;/li&gt;&lt;/ul&gt;
&lt;br /&gt;
&lt;h2&gt;Logging&lt;/h2&gt;
The code includes an easy way to configure Linq to Sql's logging feature (DataContext.Log) to write to either a text file or the System.Diagnostics.Debugger class which then appears in the output window within Visual Studio.&lt;br /&gt;&lt;br /&gt;To use this functionality you need to add the following lines into your web.config:&lt;br /&gt;&lt;br /&gt;In the &amp;lt;configSections&amp;gt; element:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
&amp;lt;section name=&amp;quot;GenericDataSection&amp;quot; type=&amp;quot;DataLayer.GenericDataSection, DataLayer&amp;quot; allowDefinition=&amp;quot;MachineToApplication&amp;quot; restartOnExternalChanges=&amp;quot;true&amp;quot; requirePermission=&amp;quot;false&amp;quot;/&amp;gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then directly after &amp;lt;configSections&amp;gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
&amp;lt;GenericDataSection LogType=&amp;quot;file&amp;quot; LogFile=&amp;quot;C:\Projects\MultiTierLinqToSql_release\test.txt&amp;quot; DeleteExistingFile=&amp;quot;true&amp;quot;/&amp;gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The first of these lines just declares the second line which is the one that contains the interesting stuff.&lt;br /&gt;There are 3 config options in this section:
&lt;ol&gt;&lt;li&gt;LogType - this can be either 'file' (logs output to a file), 'debug' (logs output to Systems.Diagnostics.Debug) or 'none' (switches logging off). &lt;/li&gt;
&lt;li&gt;LogFile - only applies when LogType is set to 'file', and the default is 'log.txt' it specifies the name of the file to use for logging.&lt;/li&gt;
&lt;li&gt;DeleteExistingFile - only applies when LogType is set to 'file', values can be 'true' or 'false', and the default is true. When this is set to true the file will be overwritten every time a new DataContext is created, effectively once per request. If set to false then all output is appended to the end of the file. This can result in a very large log files so be careful.&lt;/li&gt;&lt;/ol&gt;
&lt;h4&gt;Notes&lt;/h4&gt;
As with all file logging this can be pretty detrimental to performance and so should not be left on in production.&lt;br /&gt;&lt;br /&gt;To handle the logging to the output window I have used the DebuggerWriter class described here: &lt;a href="http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11" class="externalLink"&gt;http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;Error Handling&lt;/h2&gt;
Best practice for managing business rules relating to data integrity with Linq to Sql is to include these rules in partial methods in the entity classes and throw exceptions when they are violated (see http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx for more details).&lt;br /&gt;When using this strategy with an ObjectDataSource, you can then catch these exceptions in the OnUpdated or OnInserted events of your ObjectDataSource and present the information to the user. &lt;br /&gt;To do so you set the OnUpdated and/or the OnInserted attribute of your GenericObjectDatasource:&lt;br /&gt;&lt;pre&gt;
OnUpdated=&amp;quot;ProductDataSource_Updated&amp;quot;
OnInserted=&amp;quot;ProductDataSource_Updated&amp;quot;
&lt;/pre&gt;&lt;br /&gt;and then handle this event in your code behind:&lt;br /&gt;&lt;pre&gt;
protected void ProductDataSource_Updated(object sender, ObjectDataSourceStatusEventArgs e)
    {
        if (e.Exception != null)
        {
            //litError is a literal control which I want to use to display the error to the user
            litError.Text = e.Exception.Message;
            //This tells the objectDataSource that I have handled the error and not to throw it
            e.ExceptionHandled = true;
        }
    }
&lt;/pre&gt;&lt;br /&gt;There is an example of this in the Default.aspx page in the test website.&lt;br /&gt;
&lt;h2&gt;DataLoadOptions&lt;/h2&gt;
As has been widely noted, the way that Linq to Sql works, means that the DataLoadOptions for your DataContext need to be set &lt;i&gt;before&lt;/i&gt; any operations are carried out, and cannot subsequently be changed. This means that in my Asp.Net application I will need to set the DataLoadOptions for the whole request somewhere near the start (assuming of course that I need to set DataLoadOptions at all). It also means that my UI or business layer will need to take responsibility for this. &lt;br /&gt;&lt;br /&gt;What this means in practice is that in a classic Web forms type app I will probably set the DataLoadOptions in the OnInit event of my page, if I'm using MVC then my controller will do it. &lt;br /&gt;
&lt;h2&gt;The code&lt;/h2&gt;
The code consists of 4 projects; GenericDataLayer, which contains the reusable code and 3 demo/test projects
&lt;h3&gt;GenericDataLayer&lt;/h3&gt;
This project contains all of the code you need to use this solution, it can be compiled and referenced in your projects or run as a project within your solutions.&lt;br /&gt;It is made up of:
&lt;ul&gt;&lt;li&gt;GenericRepository class - the main class which implements the generic CRUD methods as discussed above&lt;/li&gt;
&lt;li&gt;GenericObjectDataSource - the custom ObjectDataSource to use in your aspx pages as discussed above. This control also uses the classes GenericObjectDataSourceView and ExposedSr&lt;/li&gt;
&lt;li&gt;FileLogger and DebuggerWriter - classes for logging to text files and System.Debug.Out, see Logging section&lt;/li&gt;
&lt;li&gt;GenericDataSection - a class to handle configuration data&lt;/li&gt;
&lt;li&gt;Dynamic - some code to help in the sorting methods &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;NorthWindDataLayer&lt;/h3&gt;
This project is an example of how to use the code with your database (using Microsoft's NorthWind database), it references the GenericRepository project and contains all the project specific database classes that your application needs to work with. These are:
&lt;ul&gt;&lt;li&gt;Linq to Sql dbml file - In this case pointing to the NorthWind database&lt;/li&gt;
&lt;li&gt;Partial Entity classes which implements a custom data validation rules (see section on Error Handling) - In this project there is just one class Product which implements one rule &lt;/li&gt;
&lt;li&gt;Concrete Repository classes which inherit from GenericRepository and implement custom data access code for specific database entities - This project has two, ProductRepository and CategoryRepository &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;A test web project&lt;/h3&gt;
This project has one page with a GridView and a FormView which use the data layer via GenericObjectDataSources to list all the products in the Northwind database, allow editing and deletion of those projects, and insert new products via the FormView. &lt;br /&gt;
&lt;h3&gt;A console app&lt;/h3&gt;
To test functionality outside the context of a web application &lt;br /&gt;&lt;br /&gt;To run the example project:
&lt;ul&gt;&lt;li&gt;Download and unzip the release &lt;/li&gt;
&lt;li&gt;Open the solution in VS2008&lt;/li&gt;
&lt;li&gt;Change the connection string in the web.config to point to a Northwind database&lt;/li&gt;
&lt;li&gt;Run the web project&lt;/li&gt;&lt;/ul&gt;
&lt;br /&gt;To use the code in your own projects
&lt;ul&gt;&lt;li&gt;Create a class library to contain your Linq to Sql classes, partial entities and concrete repositories&lt;/li&gt;
&lt;li&gt;Reference the GenericDataLayer project (either compiled or within your solution)&lt;/li&gt;
&lt;li&gt;Create one entity repository class for each Linq to Sql entity, inheriting from Genericrepository&lt;/li&gt;
&lt;li&gt;Optionally define any new entity specific data access operations in your entity repository classes&lt;/li&gt;
&lt;li&gt;Make use of the GenericObjectDataSource to get easy inserts, updates, deletes, sorting and paging&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;</description><author>rbates</author><pubDate>Tue, 14 Apr 2009 11:47:50 GMT</pubDate><guid isPermaLink="false">Updated Wiki: Home 20090414114750A</guid></item><item><title>Updated Wiki: Home</title><link>http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=Home&amp;version=14</link><description>&lt;div class="wikidoc"&gt;&lt;h1&gt;Multi tier architecture for Linq to Sql&lt;/h1&gt;
&lt;i&gt;I am still updating this, nothing in here is wrong, but it may be incomplete - Rupert&lt;/i&gt;&lt;br /&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
This resource shows an approach for using Linq to Sql within a multi tier Asp.Net application, and particularly how it can be made to work well with ObjectDataSources. It is here as a discussion piece as well as a usable bit of code.&lt;br /&gt;&lt;br /&gt;The key features are a Request-scoped datacontext and entity repository classes which provide easy to use Create, Retrieve, Update and Delete (CRUD) operations implemented with Generics. Also included is a T4 template for auto generation of repositories from a dbml file. &lt;br /&gt;&lt;br /&gt;
&lt;h2&gt;Entity Repository classes&lt;/h2&gt;
Each database entity has an associated repository class which is used to perform common CRUD operations. Specific entity repositorys inherit from a generic class &lt;i&gt;GenericRepository&lt;/i&gt; which already implements all the basic Select, Insert, Update &amp;amp; Delete operations.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
[System.ComponentModel.DataObject]
public class GenericRepository&amp;lt;TEntity, TDataContext&amp;gt; where TDataContext : DataContext
{
    public static List&amp;lt;TEntity&amp;gt; SelectAll()
    {
          ...
    }
    public static void Insert(TEntity entity)
    {
        ...
    }
    public static void Update(TEntity entity)
    {
        ...
    }
    public static void Delete(TEntity entity)
    {
        ...
    }
}
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Specific repositories then inherit from this by specifying the entity type which they are concerned with as well as the type of the DataContext used, as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;//ProductRepository class
public class ProductRepository : GenericRepository&amp;lt;Product, NorthwindDataContext&amp;gt;
{
}
&lt;/pre&gt;&lt;br /&gt;which allows client code such as the following:&lt;br /&gt;&lt;pre&gt;
   IList&amp;lt;Product&amp;gt; products = ProductRepository.SelectAll();
&lt;/pre&gt;&lt;br /&gt;The use of Generics means that I don't need to add any code at all into my ProductRepository to get all the standard CRUD operations in a fully type safe way. My ProductRepository class can now be customised to add any further data access methods which are specific to Products, for instance GetByCategoryId().&lt;br /&gt;
&lt;h2&gt;Request scoped DataContext&lt;/h2&gt;
The second part of this solution is the request scoped DataContext. This is a pattern that is commonly used with the Hibernate OR mapper as well as elsewhere, and it means that there is only ever one DataContext per Http request which is stored in the HttpContext.Items collection. It is implemented as a protected property of the GenericRepository class as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
        protected static TDataContext DataContext
        {
            get
            {
                //We are in a web app, use a request scope
                if (HttpContext.Current != null)
                {
                    TDataContext dataContext = (TDataContext)HttpContext.Current.Items[DataContextKey];
                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        HttpContext.Current.Items.Add(DataContextKey, dataContext);
                    }
                    return dataContext;
                }
                else
                {

                    // Creates a Thread Scoped DataContext object that can be reused. 
                    // The DataContext is stored in Thread local storage.
                    // See here http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=361
                    //for a discussion of this code.

                    LocalDataStoreSlot threadData = Thread.GetNamedDataSlot(DataContextKey);
                    object dataContext = null;

                    if (threadData != null)
                        dataContext = Thread.GetData(threadData);

                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        if(threadData == null)
                            threadData = Thread.AllocateNamedDataSlot(DataContextKey);

                        Thread.SetData(threadData, dataContext);
                    }
                    return (TDataContext) dataContext;
                }

            }
        }
&lt;/pre&gt;&lt;br /&gt;As you can see from the code above it handles being used outside a web app by storing the DataContext in a named data slot on the thread it is running in.&lt;br /&gt;&lt;br /&gt;The usefulness of this approach can be seen if you consider a page which uses a number of ObjectDataSources; if we configure our ObjectDataSource to use the DataContext directly then each one will create and dispose of a new DataContext this will not only quickly become a performance overhead, but will also present us with a problem when specifying LoadOptions for the DataContext resulting in more complex, less maintainable code or quite possibly code which doesn't specify loading options at all.&lt;br /&gt;&lt;br /&gt;It should be noted that this approach means that if I have a CategoryRepository class as well as a ProductRepository class, both of which inherit from GenericRepository, both of these classes will use the same DataContext. In other words the DataContext is shared across the whole request, not just by one class type.&lt;br /&gt;
&lt;h2&gt;Custom ObjectDataSource&lt;/h2&gt;
In order for updates to work correctly with databinding it is advisable to use the GenericObjectDataSource control which is included in the DataLayer project. An ordinary ObjectDataSource control will create a new object before doing updates and if there are any unbound properties on this object, they will be left with their default values which will then be saved to the database, the GenericObjectDataSource control gets round this by retrieving the original values from the database, before updating them. For more discussions of the details behind this, see &lt;a href="https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488" class="externalLink"&gt;https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;Submitting changes&lt;/h2&gt;
Another feature of the Linq to Sql architecture is the way that changes are only submitted to the database when the SubmitChanges() method is called on the DataContext. This means that we must either decide at which point to call SubmitChanges() or delegate this responsibility to client code.&lt;br /&gt;To make the classes as flexible as possible any operations which require a call to SubmitChanges (Insert, Update and Delete), are provided with a boolean parameter which specify whether to submit changes immediately or not. There is also an overload of these methods without this parameter which is equivalent to passing true (again this makes use of ObjectDatasources much more straightforward).&lt;br /&gt;The SubmitChanges method of the DataContext is also exposed through the repository class to give Client code the ability to call this explicitly.&lt;br /&gt;
&lt;h2&gt;Sorting and Paging with GridViews&lt;/h2&gt;
There are a number of methods on the GenericRepository class to automatically support paging and sorting in GridViews.&lt;br /&gt;These are:&lt;br /&gt;&lt;pre&gt;
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(int maximumRows, int startRowIndex)
        {
            ...
        }
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression)
        {
         ...
        }
     
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression, int maximumRows, int startRowIndex)
        {
            ...
        }
        public static int Count()
        {
            ...
        }
&lt;/pre&gt;&lt;br /&gt;To use this functionality all you need to do is turn it on in the ObjectDataSource and GridView with the following attributes:&lt;br /&gt;ObjectDataSource: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
EnablePaging=&amp;quot;true&amp;quot; SelectCountMethod=&amp;quot;Count&amp;quot; SortParameterName=&amp;quot;sortExpression&amp;quot;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Gridview:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
AllowPaging=&amp;quot;true&amp;quot; AllowSorting=&amp;quot;true&amp;quot;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And hey presto it just works! This makes it really easy to create sortable, pagable GridViews with no extra coding.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;This release also includes some code from Scott Gu's blog to support Dynamic Querying, see &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx" class="externalLink"&gt;http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; for more details&lt;/i&gt;&lt;br /&gt;
&lt;h2&gt;T4 Template&lt;/h2&gt;
Included in the source code is a &lt;a href="http:// T4 template : http://www.google.co.uk/search?hl=en&amp;amp;q=t4+templates&amp;amp;btnG=Google+Search&amp;amp;meta=&amp;amp;aq=0&amp;amp;oq=t4+tem" class="externalLink"&gt; T4 template : http://www.google.co.uk/search?hl=en&amp;amp;q=t4+templates&amp;amp;btnG=Google+Search&amp;amp;meta=&amp;amp;aq=0&amp;amp;oq=t4+tem&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; which will generate entities and concrete repositories (both static and non-static) with interfaces to facilitate testing. To use it you need to do the following
&lt;ul&gt;&lt;li&gt;copy the files DataClasses.tt and L2ST4.ttinclude from the T4Templates directory into your project specific datalayer project&lt;/li&gt;
&lt;li&gt;ensure that DataClasses.tt has the same name as the dbml file (so in the example Northwind project DataClasses.tt has been renamed to Northwind.tt to match Northwind.dbml)&lt;/li&gt;
&lt;li&gt;to generate the classes, open DataClasses.tt (or whatever it is now called) and save it. You will probably get a dialog box asking if you are sure you  want to do this, click Ok. All the classes will then be generated in a file called &lt;i&gt;DataClasses.generated.cs&lt;/i&gt; where &lt;i&gt;DataClasses&lt;/i&gt; is the same as the name of your dbml file.&lt;/li&gt;&lt;/ul&gt;
&lt;br /&gt;
&lt;h2&gt;Logging&lt;/h2&gt;
The code includes an easy way to configure Linq to Sql's logging feature (DataContext.Log) to write to either a text file or the System.Diagnostics.Debugger class which then appears in the output window within Visual Studio.&lt;br /&gt;&lt;br /&gt;To use this functionality you need to add the following lines into your web.config:&lt;br /&gt;&lt;br /&gt;In the &amp;lt;configSections&amp;gt; element:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
&amp;lt;section name=&amp;quot;GenericDataSection&amp;quot; type=&amp;quot;DataLayer.GenericDataSection, DataLayer&amp;quot; allowDefinition=&amp;quot;MachineToApplication&amp;quot; restartOnExternalChanges=&amp;quot;true&amp;quot; requirePermission=&amp;quot;false&amp;quot;/&amp;gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then directly after &amp;lt;configSections&amp;gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
&amp;lt;GenericDataSection LogType=&amp;quot;file&amp;quot; LogFile=&amp;quot;C:\Projects\MultiTierLinqToSql_release\test.txt&amp;quot; DeleteExistingFile=&amp;quot;true&amp;quot;/&amp;gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The first of these lines just declares the second line which is the one that contains the interesting stuff.&lt;br /&gt;There are 3 config options in this section:
&lt;ol&gt;&lt;li&gt;LogType - this can be either 'file' (logs output to a file), 'debug' (logs output to Systems.Diagnostics.Debug) or 'none' (switches logging off). &lt;/li&gt;
&lt;li&gt;LogFile - only applies when LogType is set to 'file', and the default is 'log.txt' it specifies the name of the file to use for logging.&lt;/li&gt;
&lt;li&gt;DeleteExistingFile - only applies when LogType is set to 'file', values can be 'true' or 'false', and the default is true. When this is set to true the file will be overwritten every time a new DataContext is created, effectively once per request. If set to false then all output is appended to the end of the file. This can result in a very large log files so be careful.&lt;/li&gt;&lt;/ol&gt;
&lt;h4&gt;Notes&lt;/h4&gt;
As with all file logging this can be pretty detrimental to performance and so should not be left on in production.&lt;br /&gt;&lt;br /&gt;To handle the logging to the output window I have used the DebuggerWriter class described here: &lt;a href="http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11" class="externalLink"&gt;http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;Error Handling&lt;/h2&gt;
Best practice for managing business rules relating to data integrity with Linq to Sql is to include these rules in partial methods in the entity classes and throw exceptions when they are violated (see http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx for more details).&lt;br /&gt;When using this strategy with an ObjectDataSource, you can then catch these exceptions in the OnUpdated or OnInserted events of your ObjectDataSource and present the information to the user. &lt;br /&gt;To do so you set the OnUpdated and/or the OnInserted attribute of your GenericObjectDatasource:&lt;br /&gt;&lt;pre&gt;
OnUpdated=&amp;quot;ProductDataSource_Updated&amp;quot;
OnInserted=&amp;quot;ProductDataSource_Updated&amp;quot;
&lt;/pre&gt;&lt;br /&gt;and then handle this event in your code behind:&lt;br /&gt;&lt;pre&gt;
protected void ProductDataSource_Updated(object sender, ObjectDataSourceStatusEventArgs e)
    {
        if (e.Exception != null)
        {
            //litError is a literal control which I want to use to display the error to the user
            litError.Text = e.Exception.Message;
            //This tells the objectDataSource that I have handled the error and not to throw it
            e.ExceptionHandled = true;
        }
    }
&lt;/pre&gt;&lt;br /&gt;There is an example of this in the Default.aspx page in the test website.&lt;br /&gt;
&lt;h2&gt;DataLoadOptions&lt;/h2&gt;
As has been widely noted, the way that Linq to Sql works, means that the DataLoadOptions for your DataContext need to be set &lt;i&gt;before&lt;/i&gt; any operations are carried out, and cannot subsequently be changed. This means that in my Asp.Net application I will need to set the DataLoadOptions for the whole request somewhere near the start (assuming of course that I need to set DataLoadOptions at all). It also means that my UI or business layer will need to take responsibility for this. &lt;br /&gt;&lt;br /&gt;What this means in practice is that in a classic Web forms type app I will probably set the DataLoadOptions in the OnInit event of my page, if I'm using MVC then my controller will do it. &lt;br /&gt;
&lt;h2&gt;The code&lt;/h2&gt;
The code consists of 4 projects; GenericDataLayer, which contains the reusable code and 3 demo/test projects
&lt;h3&gt;GenericDataLayer&lt;/h3&gt;
This project contains all of the code you need to use this solution, it can be compiled and referenced in your projects or run as a project within your solutions.&lt;br /&gt;It is made up of:
&lt;ul&gt;&lt;li&gt;GenericRepository class - the main class which implements the generic CRUD methods as discussed above&lt;/li&gt;
&lt;li&gt;GenericObjectDataSource - the custom ObjectDataSource to use in your aspx pages as discussed above. This control also uses the classes GenericObjectDataSourceView and ExposedSr&lt;/li&gt;
&lt;li&gt;FileLogger and DebuggerWriter - classes for logging to text files and System.Debug.Out, see Logging section&lt;/li&gt;
&lt;li&gt;GenericDataSection - a class to handle configuration data&lt;/li&gt;
&lt;li&gt;Dynamic - some code to help in the sorting methods &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;NorthWindDataLayer&lt;/h3&gt;
This project is an example of how to use the code with your database (using Microsoft's NorthWind database), it references the GenericRepository project and contains all the project specific database classes that your application needs to work with. These are:
&lt;ul&gt;&lt;li&gt;Linq to Sql dbml file - In this case pointing to the NorthWind database&lt;/li&gt;
&lt;li&gt;Partial Entity classes which implements a custom data validation rules (see section on Error Handling) - In this project there is just one class Product which implements one rule &lt;/li&gt;
&lt;li&gt;Concrete Repository classes which inherit from GenericRepository and implement custom data access code for specific database entities - This project has two, ProductRepository and CategoryRepository &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;A test web project&lt;/h3&gt;
This project has one page with a GridView and a FormView which use the data layer via GenericObjectDataSources to list all the products in the Northwind database, allow editing and deletion of those projects, and insert new products via the FormView. &lt;br /&gt;
&lt;h3&gt;A console app&lt;/h3&gt;
To test functionality outside the context of a web application &lt;br /&gt;&lt;br /&gt;To run the example project:
&lt;ul&gt;&lt;li&gt;Download and unzip the release &lt;/li&gt;
&lt;li&gt;Open the solution in VS2008&lt;/li&gt;
&lt;li&gt;Change the connection string in the web.config to point to a Northwind database&lt;/li&gt;
&lt;li&gt;Run the web project&lt;/li&gt;&lt;/ul&gt;
&lt;br /&gt;To use the code in your own projects
&lt;ul&gt;&lt;li&gt;Create a class library to contain your Linq to Sql classes, partial entities and concrete repositories&lt;/li&gt;
&lt;li&gt;Reference the GenericDataLayer project (either compiled or within your solution)&lt;/li&gt;
&lt;li&gt;Create one entity repository class for each Linq to Sql entity, inheriting from Genericrepository&lt;/li&gt;
&lt;li&gt;Optionally define any new entity specific data access operations in your entity repository classes&lt;/li&gt;
&lt;li&gt;Make use of the GenericObjectDataSource to get easy inserts, updates, deletes, sorting and paging&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;</description><author>rbates</author><pubDate>Tue, 14 Apr 2009 11:41:40 GMT</pubDate><guid isPermaLink="false">Updated Wiki: Home 20090414114140A</guid></item><item><title>Updated Wiki: Home</title><link>http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=Home&amp;version=13</link><description>&lt;div class="wikidoc"&gt;&lt;h1&gt;Multi tier architecture for Linq to Sql&lt;/h1&gt;
&lt;i&gt;I am still updating this, nothing in here is wrong, but it may be incomplete - Rupert&lt;/i&gt;&lt;br /&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
This resource shows an approach for using Linq to Sql within a multi tier Asp.Net application, and particularly how it can be made to work well with ObjectDataSources. It is here as a discussion piece as well as a usable bit of code.&lt;br /&gt;&lt;br /&gt;The key features are a Request-scoped datacontext and entity repository classes which provide easy to use Create, Retrieve, Update and Delete (CRUD) operations implemented with Generics. Also included is a T4 template for auto generation of repositories from a dbml file. &lt;br /&gt;&lt;br /&gt;
&lt;h2&gt;Entity Repository classes&lt;/h2&gt;
Each database entity has an associated repository class which is used to perform common CRUD operations. Specific entity repositorys inherit from a generic class &lt;i&gt;GenericRepository&lt;/i&gt; which already implements all the basic Select, Insert, Update &amp;amp; Delete operations.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
[System.ComponentModel.DataObject]
public class GenericRepository&amp;lt;TEntity, TDataContext&amp;gt; where TDataContext : DataContext
{
    public static List&amp;lt;TEntity&amp;gt; SelectAll()
    {
          ...
    }
    public static void Insert(TEntity entity)
    {
        ...
    }
    public static void Update(TEntity entity)
    {
        ...
    }
    public static void Delete(TEntity entity)
    {
        ...
    }
}
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Specific repositories then inherit from this by specifying the entity type which they are concerned with as well as the type of the DataContext used, as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;//ProductRepository class
public class ProductRepository : GenericRepository&amp;lt;Product, NorthwindDataContext&amp;gt;
{
}
&lt;/pre&gt;&lt;br /&gt;which allows client code such as the following:&lt;br /&gt;&lt;pre&gt;
   IList&amp;lt;Product&amp;gt; products = ProductRepository.SelectAll();
&lt;/pre&gt;&lt;br /&gt;The use of Generics means that I don't need to add any code at all into my ProductRepository to get all the standard CRUD operations in a fully type safe way. My ProductRepository class can now be customised to add any further data access methods which are specific to Products, for instance GetByCategoryId().&lt;br /&gt;
&lt;h2&gt;Request scoped DataContext&lt;/h2&gt;
The second part of this solution is the request scoped DataContext. This is a pattern that is commonly used with the Hibernate OR mapper as well as elsewhere, and it means that there is only ever one DataContext per Http request which is stored in the HttpContext.Items collection. It is implemented as a protected property of the GenericRepository class as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
        protected static TDataContext DataContext
        {
            get
            {
                //We are in a web app, use a request scope
                if (HttpContext.Current != null)
                {
                    TDataContext dataContext = (TDataContext)HttpContext.Current.Items[DataContextKey];
                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        HttpContext.Current.Items.Add(DataContextKey, dataContext);
                    }
                    return dataContext;
                }
                else
                {

                    // Creates a Thread Scoped DataContext object that can be reused. 
                    // The DataContext is stored in Thread local storage.
                    // See here http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=361
                    //for a discussion of this code.

                    LocalDataStoreSlot threadData = Thread.GetNamedDataSlot(DataContextKey);
                    object dataContext = null;

                    if (threadData != null)
                        dataContext = Thread.GetData(threadData);

                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        if(threadData == null)
                            threadData = Thread.AllocateNamedDataSlot(DataContextKey);

                        Thread.SetData(threadData, dataContext);
                    }
                    return (TDataContext) dataContext;
                }

            }
        }
&lt;/pre&gt;&lt;br /&gt;As you can see from the code above it handles being used outside a web app by storing the DataContext in a named data slot on the thread it is running in.&lt;br /&gt;&lt;br /&gt;The usefulness of this approach can be seen if you consider a page which uses a number of ObjectDataSources; if we configure our ObjectDataSource to use the DataContext directly then each one will create and dispose of a new DataContext this will not only quickly become a performance overhead, but will also present us with a problem when specifying LoadOptions for the DataContext resulting in more complex, less maintainable code or quite possibly code which doesn't specify loading options at all.&lt;br /&gt;&lt;br /&gt;It should be noted that this approach means that if I have a CategoryRepository class as well as a ProductRepository class, both of which inherit from GenericRepository, both of these classes will use the same DataContext. In other words the DataContext is shared across the whole request, not just by one class type.&lt;br /&gt;
&lt;h2&gt;Custom ObjectDataSource&lt;/h2&gt;
In order for updates to work correctly with databinding it is advisable to use the GenericObjectDataSource control which is included in the DataLayer project. An ordinary ObjectDataSource control will create a new object before doing updates and if there are any unbound properties on this object, they will be left with their default values which will then be saved to the database, the GenericObjectDataSource control gets round this by retrieving the original values from the database, before updating them. For more discussions of the details behind this, see &lt;a href="https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488" class="externalLink"&gt;https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;Submitting changes&lt;/h2&gt;
Another feature of the Linq to Sql architecture is the way that changes are only submitted to the database when the SubmitChanges() method is called on the DataContext. This means that we must either decide at which point to call SubmitChanges() or delegate this responsibility to client code.&lt;br /&gt;To make the classes as flexible as possible any operations which require a call to SubmitChanges (Insert, Update and Delete), are provided with a boolean parameter which specify whether to submit changes immediately or not. There is also an overload of these methods without this parameter which is equivalent to passing true (again this makes use of ObjectDatasources much more straightforward).&lt;br /&gt;The SubmitChanges method of the DataContext is also exposed through the repository class to give Client code the ability to call this explicitly.&lt;br /&gt;
&lt;h2&gt;Sorting and Paging with GridViews&lt;/h2&gt;
There are a number of methods on the GenericRepository class to automatically support paging and sorting in GridViews.&lt;br /&gt;These are:&lt;br /&gt;&lt;pre&gt;
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(int maximumRows, int startRowIndex)
        {
            ...
        }
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression)
        {
         ...
        }
     
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression, int maximumRows, int startRowIndex)
        {
            ...
        }
        public static int Count()
        {
            ...
        }
&lt;/pre&gt;&lt;br /&gt;To use this functionality all you need to do is turn it on in the ObjectDataSource and GridView with the following attributes:&lt;br /&gt;ObjectDataSource: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
EnablePaging=&amp;quot;true&amp;quot; SelectCountMethod=&amp;quot;Count&amp;quot; SortParameterName=&amp;quot;sortExpression&amp;quot;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Gridview:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
AllowPaging=&amp;quot;true&amp;quot; AllowSorting=&amp;quot;true&amp;quot;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And hey presto it just works! This makes it really easy to create sortable, pagable GridViews with no extra coding.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;This release also includes some code from Scott Gu's blog to support Dynamic Querying, see &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx" class="externalLink"&gt;http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; for more details&lt;/i&gt;&lt;br /&gt;
&lt;h2&gt;T4 Template&lt;/h2&gt;
Included in the source code is a &lt;a href="http:// T4 template : http://www.google.co.uk/search?hl=en&amp;amp;q=t4+templates&amp;amp;btnG=Google+Search&amp;amp;meta=&amp;amp;aq=0&amp;amp;oq=t4+tem" class="externalLink"&gt; T4 template : http://www.google.co.uk/search?hl=en&amp;amp;q=t4+templates&amp;amp;btnG=Google+Search&amp;amp;meta=&amp;amp;aq=0&amp;amp;oq=t4+tem&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; which will generate entities and concrete repositories (both static and non-static) with interfaces to facilitate testing. To use it you need to do the following
&lt;ul&gt;&lt;li&gt;copy the files DataClasses.tt and L2ST4.ttinclude from the T4Templates directory into your project specific datalayer project&lt;/li&gt;
&lt;li&gt;ensure that DataClasses.tt has the same name as the dbml file (so in the example Northwind project DataClasses.tt has been renamed to Northwind.tt to match Northwind.dbml)&lt;/li&gt;
&lt;li&gt;to generate the classes, open DataClasses.tt (or whatever it is now called) and save it. You will probably get a dialog box asking if you are sure you  want to do this, click Ok. All the classes will then be generated in a file called &lt;a href="http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=DataClasses"&gt;DataClasses&lt;/a&gt;.generated.cs where &lt;a href="http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=DataClasses"&gt;DataClasses&lt;/a&gt; is whatever you renamed DataClasses.tt to.&lt;/li&gt;&lt;/ul&gt;
&lt;br /&gt;
&lt;h2&gt;Logging&lt;/h2&gt;
The code includes an easy way to configure Linq to Sql's logging feature (DataContext.Log) to write to either a text file or the System.Diagnostics.Debugger class which then appears in the output window within Visual Studio.&lt;br /&gt;&lt;br /&gt;To use this functionality you need to add the following lines into your web.config:&lt;br /&gt;&lt;br /&gt;In the &amp;lt;configSections&amp;gt; element:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
&amp;lt;section name=&amp;quot;GenericDataSection&amp;quot; type=&amp;quot;DataLayer.GenericDataSection, DataLayer&amp;quot; allowDefinition=&amp;quot;MachineToApplication&amp;quot; restartOnExternalChanges=&amp;quot;true&amp;quot; requirePermission=&amp;quot;false&amp;quot;/&amp;gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then directly after &amp;lt;configSections&amp;gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
&amp;lt;GenericDataSection LogType=&amp;quot;file&amp;quot; LogFile=&amp;quot;C:\Projects\MultiTierLinqToSql_release\test.txt&amp;quot; DeleteExistingFile=&amp;quot;true&amp;quot;/&amp;gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The first of these lines just declares the second line which is the one that contains the interesting stuff.&lt;br /&gt;There are 3 config options in this section:
&lt;ol&gt;&lt;li&gt;LogType - this can be either 'file' (logs output to a file), 'debug' (logs output to Systems.Diagnostics.Debug) or 'none' (switches logging off). &lt;/li&gt;
&lt;li&gt;LogFile - only applies when LogType is set to 'file', and the default is 'log.txt' it specifies the name of the file to use for logging.&lt;/li&gt;
&lt;li&gt;DeleteExistingFile - only applies when LogType is set to 'file', values can be 'true' or 'false', and the default is true. When this is set to true the file will be overwritten every time a new DataContext is created, effectively once per request. If set to false then all output is appended to the end of the file. This can result in a very large log files so be careful.&lt;/li&gt;&lt;/ol&gt;
&lt;h4&gt;Notes&lt;/h4&gt;
As with all file logging this can be pretty detrimental to performance and so should not be left on in production.&lt;br /&gt;&lt;br /&gt;To handle the logging to the output window I have used the DebuggerWriter class described here: &lt;a href="http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11" class="externalLink"&gt;http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;Error Handling&lt;/h2&gt;
Best practice for managing business rules relating to data integrity with Linq to Sql is to include these rules in partial methods in the entity classes and throw exceptions when they are violated (see http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx for more details).&lt;br /&gt;When using this strategy with an ObjectDataSource, you can then catch these exceptions in the OnUpdated or OnInserted events of your ObjectDataSource and present the information to the user. &lt;br /&gt;To do so you set the OnUpdated and/or the OnInserted attribute of your GenericObjectDatasource:&lt;br /&gt;&lt;pre&gt;
OnUpdated=&amp;quot;ProductDataSource_Updated&amp;quot;
OnInserted=&amp;quot;ProductDataSource_Updated&amp;quot;
&lt;/pre&gt;&lt;br /&gt;and then handle this event in your code behind:&lt;br /&gt;&lt;pre&gt;
protected void ProductDataSource_Updated(object sender, ObjectDataSourceStatusEventArgs e)
    {
        if (e.Exception != null)
        {
            //litError is a literal control which I want to use to display the error to the user
            litError.Text = e.Exception.Message;
            //This tells the objectDataSource that I have handled the error and not to throw it
            e.ExceptionHandled = true;
        }
    }
&lt;/pre&gt;&lt;br /&gt;There is an example of this in the Default.aspx page in the test website.&lt;br /&gt;
&lt;h2&gt;DataLoadOptions&lt;/h2&gt;
As has been widely noted, the way that Linq to Sql works, means that the DataLoadOptions for your DataContext need to be set &lt;i&gt;before&lt;/i&gt; any operations are carried out, and cannot subsequently be changed. This means that in my Asp.Net application I will need to set the DataLoadOptions for the whole request somewhere near the start (assuming of course that I need to set DataLoadOptions at all). It also means that my UI or business layer will need to take responsibility for this. &lt;br /&gt;&lt;br /&gt;What this means in practice is that in a classic Web forms type app I will probably set the DataLoadOptions in the OnInit event of my page, if I'm using MVC then my controller will do it. &lt;br /&gt;
&lt;h2&gt;The code&lt;/h2&gt;
The code consists of 4 projects; GenericDataLayer, which contains the reusable code and 3 demo/test projects
&lt;h3&gt;GenericDataLayer&lt;/h3&gt;
This project contains all of the code you need to use this solution, it can be compiled and referenced in your projects or run as a project within your solutions.&lt;br /&gt;It is made up of:
&lt;ul&gt;&lt;li&gt;GenericRepository class - the main class which implements the generic CRUD methods as discussed above&lt;/li&gt;
&lt;li&gt;GenericObjectDataSource - the custom ObjectDataSource to use in your aspx pages as discussed above. This control also uses the classes GenericObjectDataSourceView and ExposedSr&lt;/li&gt;
&lt;li&gt;FileLogger and DebuggerWriter - classes for logging to text files and System.Debug.Out, see Logging section&lt;/li&gt;
&lt;li&gt;GenericDataSection - a class to handle configuration data&lt;/li&gt;
&lt;li&gt;Dynamic - some code to help in the sorting methods &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;NorthWindDataLayer&lt;/h3&gt;
This project is an example of how to use the code with your database (using Microsoft's NorthWind database), it references the GenericRepository project and contains all the project specific database classes that your application needs to work with. These are:
&lt;ul&gt;&lt;li&gt;Linq to Sql dbml file - In this case pointing to the NorthWind database&lt;/li&gt;
&lt;li&gt;Partial Entity classes which implements a custom data validation rules (see section on Error Handling) - In this project there is just one class Product which implements one rule &lt;/li&gt;
&lt;li&gt;Concrete Repository classes which inherit from GenericRepository and implement custom data access code for specific database entities - This project has two, ProductRepository and CategoryRepository &lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;A test web project&lt;/h3&gt;
This project has one page with a GridView and a FormView which use the data layer via GenericObjectDataSources to list all the products in the Northwind database, allow editing and deletion of those projects, and insert new products via the FormView. &lt;br /&gt;
&lt;h3&gt;A console app&lt;/h3&gt;
To test functionality outside the context of a web application &lt;br /&gt;&lt;br /&gt;To run the example project:
&lt;ul&gt;&lt;li&gt;Download and unzip the release &lt;/li&gt;
&lt;li&gt;Open the solution in VS2008&lt;/li&gt;
&lt;li&gt;Change the connection string in the web.config to point to a Northwind database&lt;/li&gt;
&lt;li&gt;Run the web project&lt;/li&gt;&lt;/ul&gt;
&lt;br /&gt;To use the code in your own projects
&lt;ul&gt;&lt;li&gt;Create a class library to contain your Linq to Sql classes, partial entities and concrete repositories&lt;/li&gt;
&lt;li&gt;Reference the GenericDataLayer project (either compiled or within your solution)&lt;/li&gt;
&lt;li&gt;Create one entity repository class for each Linq to Sql entity, inheriting from Genericrepository&lt;/li&gt;
&lt;li&gt;Optionally define any new entity specific data access operations in your entity repository classes&lt;/li&gt;
&lt;li&gt;Make use of the GenericObjectDataSource to get easy inserts, updates, deletes, sorting and paging&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;</description><author>rbates</author><pubDate>Tue, 14 Apr 2009 11:39:11 GMT</pubDate><guid isPermaLink="false">Updated Wiki: Home 20090414113911A</guid></item><item><title>Updated Wiki: Home</title><link>http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=Home&amp;version=12</link><description>&lt;div class="wikidoc"&gt;
&lt;h1&gt;
Multi tier architecture for Linq to Sql
&lt;/h1&gt;&lt;i&gt;I am still updating this, nothing in here is wrong, but it may be incomplete - Rupert&lt;/i&gt;&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Introduction
&lt;/h2&gt;This resource shows an approach for using Linq to Sql within a multi tier Asp.Net application, and particularly how it can be made to work well with ObjectDataSources. It is here as a discussion piece as well as a usable bit of code.&lt;br /&gt; &lt;br /&gt;The key features are a Request-scoped datacontext and entity repository classes which provide easy to use Create, Retrieve, Update and Delete (CRUD) operations implemented with Generics. Also included is a T4 template for auto generation of repositories from a dbml file. &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Entity Repository classes
&lt;/h2&gt;Each database entity has an associated repository class which is used to perform common CRUD operations. Specific entity controllers inherit from a generic class &lt;i&gt;GenericController&lt;/i&gt; which already implements all the basic Select, Insert, Update &amp;amp; Delete operations.&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
[System.ComponentModel.DataObject]
public class GenericController&amp;lt;TEntity, TDataContext&amp;gt; where TDataContext : DataContext
{
    public static List&amp;lt;TEntity&amp;gt; SelectAll()
    {
          ...
    }
    public static void Insert(TEntity entity)
    {
        ...
    }
    public static void Update(TEntity entity)
    {
        ...
    }
    public static void Delete(TEntity entity)
    {
        ...
    }
}
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;Specific repositories then inherit from this by specifying the entity type which they are concerned with as well as the type of the DataContext used, as follows:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
//ProductController class
public class ProductController : GenericController&amp;lt;Product, NorthwindDataContext&amp;gt;
{
}
&lt;/pre&gt; &lt;br /&gt;which allows client code such as the following:&lt;br /&gt;&lt;pre&gt;
   IList&amp;lt;Product&amp;gt; products = ProductController.SelectAll();
&lt;/pre&gt; &lt;br /&gt;The use of Generics means that I don't need to add any code at all into my ProductController to get all the standard CRUD operations in a fully type safe way. My ProductController class can now be customised to add any further data access methods which are specific to Products, for instance GetByCategoryId().&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Request scoped DataContext
&lt;/h2&gt;The second part of this solution is the request scoped DataContext. This is a pattern that is commonly used with the Hibernate OR mapper as well as elsewhere, and it means that there is only ever one DataContext per Http request which is stored in the HttpContext.Items collection. It is implemented as a protected property of the GenericController class as follows:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
        protected static TDataContext DataContext
        {
            get
            {
                //We are in a web app, use a request scope
                if (HttpContext.Current != null)
                {
                    TDataContext dataContext = (TDataContext)HttpContext.Current.Items[DataContextKey];
                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        HttpContext.Current.Items.Add(DataContextKey, dataContext);
                    }
                    return dataContext;
                }
                else
                {
 
                    // Creates a Thread Scoped DataContext object that can be reused. 
                    // The DataContext is stored in Thread local storage.
                    // See here http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=361
                    //for a discussion of this code.
 
                    LocalDataStoreSlot threadData = Thread.GetNamedDataSlot(DataContextKey);
                    object dataContext = null;
 
                    if (threadData != null)
                        dataContext = Thread.GetData(threadData);
 
                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        if(threadData == null)
                            threadData = Thread.AllocateNamedDataSlot(DataContextKey);
 
                        Thread.SetData(threadData, dataContext);
                    }
                    return (TDataContext) dataContext;
                }
 
            }
        }
&lt;/pre&gt; &lt;br /&gt;As you can see from the code above it handles being used outside a web app by storing the DataContext in a named data slot on the thread it is running in.&lt;br /&gt; &lt;br /&gt;The usefulness of this approach can be seen if you consider a page which uses a number of ObjectDataSources; if we configure our ObjectDataSource to use the DataContext directly then each one will create and dispose of a new DataContext this will not only quickly become a performance overhead, but will also present us with a problem when specifying LoadOptions for the DataContext resulting in more complex, less maintainable code or quite possibly code which doesn't specify loading options at all.&lt;br /&gt; &lt;br /&gt;It should be noted that this approach means that if I have a CategoryController class as well as a ProductController class, both of which inherit from GenericController, both of these classes will use the same DataContext. In other words the DataContext is shared across the whole request, not just by one class type.&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Custom ObjectDataSource
&lt;/h2&gt;In order for updates to work correctly with databinding it is advisable to use the GenericObjectDataSource control which is included in the DataLayer project. An ordinary ObjectDataSource control will create a new object before doing updates and if there are any unbound properties on this object, they will be left with their default values which will then be saved to the database, the GenericObjectDataSource control gets round this by retrieving the original values from the database, before updating them. For more discussions of the details behind this, see &lt;a href="https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488" class="externalLink"&gt;https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Submitting changes
&lt;/h2&gt;Another feature of the Linq to Sql architecture is the way that changes are only submitted to the database when the SubmitChanges() method is called on the DataContext. This means that we must either decide at which point to call SubmitChanges() or delegate this responsibility to client code.&lt;br /&gt;To make the classes as flexible as possible any operations which require a call to SubmitChanges (Insert, Update and Delete), are provided with a boolean parameter which specify whether to submit changes immediately or not. There is also an overload of these methods without this parameter which is equivalent to passing true (again this makes use of ObjectDatasources much more straightforward).&lt;br /&gt;The SubmitChanges method of the DataContext is also exposed through the controller class to give Client code the ability to call this explicitly.&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Sorting and Paging with GridViews
&lt;/h2&gt;There are a number of methods on the GenericController class to automatically support paging and sorting in GridViews.&lt;br /&gt;These are:&lt;br /&gt;&lt;pre&gt;
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(int maximumRows, int startRowIndex)
        {
            ...
        }
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression)
        {
         ...
        }
     
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression, int maximumRows, int startRowIndex)
        {
            ...
        }
        public static int Count()
        {
            ...
        }
&lt;/pre&gt; &lt;br /&gt;To use this functionality all you need to do is turn it on in the ObjectDataSource and GridView with the following attributes:&lt;br /&gt;ObjectDataSource: &lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
EnablePaging=&amp;quot;true&amp;quot; SelectCountMethod=&amp;quot;Count&amp;quot; SortParameterName=&amp;quot;sortExpression&amp;quot;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;Gridview:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
AllowPaging=&amp;quot;true&amp;quot; AllowSorting=&amp;quot;true&amp;quot;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;And hey presto it just works! This makes it really easy to create sortable, pagable GridViews with no extra coding.&lt;br /&gt; &lt;br /&gt;&lt;i&gt;This release also includes some code from Scott Gu's blog to support Dynamic Querying, see &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx" class="externalLink"&gt;http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; for more details&lt;/i&gt;&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
T4 Template
&lt;/h2&gt;Included in the source code is a &lt;a href="T4%20template%20:%20http://www.google.co.uk/search?hl=en&amp;amp;q=t4+templates&amp;amp;btnG=Google+Search&amp;amp;meta=&amp;amp;aq=0&amp;amp;oq=t4+tem" class="externalLink"&gt;T4 template : http://www.google.co.uk/search?hl=en&amp;amp;q=t4+templates&amp;amp;btnG=Google+Search&amp;amp;meta=&amp;amp;aq=0&amp;amp;oq=t4+tem&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; which will generate entities and concrete repositories (both static and non-static) with interfaces to facilitate testing. To use it you need to do the following&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;copy the files DataClasses.tt and L2ST4.ttinclude from the T4Templates directory into your project specific datalayer project&lt;/li&gt;&lt;li&gt;ensure that DataClasses.tt has the same name as the dbml file (so in the example Northwind project DataClasses.tt has been renamed to Northwind.tt to match Northwind.dbml)&lt;/li&gt;&lt;li&gt;to generate the classes, open DataClasses.tt (or whatever it is now called) and save it. You will probably get a dialog box asking if you are sure you  want to do this, click Ok. All the classes will then be generated in a file called &lt;a href="http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=DataClasses&amp;amp;referringTitle=Home"&gt;DataClasses&lt;/a&gt;.generated.cs where &lt;a href="http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=DataClasses&amp;amp;referringTitle=Home"&gt;DataClasses&lt;/a&gt; is whatever you renamed DataClasses.tt to.&lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Logging
&lt;/h2&gt;The code includes an easy way to configure Linq to Sql's logging feature (DataContext.Log) to write to either a text file or the System.Diagnostics.Debugger class which then appears in the output window within Visual Studio.&lt;br /&gt; &lt;br /&gt;To use this functionality you need to add the following lines into your web.config:&lt;br /&gt; &lt;br /&gt;In the &amp;lt;configSections&amp;gt; element:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
&amp;lt;section name=&amp;quot;GenericDataSection&amp;quot; type=&amp;quot;DataLayer.GenericDataSection, DataLayer&amp;quot; allowDefinition=&amp;quot;MachineToApplication&amp;quot; restartOnExternalChanges=&amp;quot;true&amp;quot; requirePermission=&amp;quot;false&amp;quot;/&amp;gt;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;Then directly after &amp;lt;configSections&amp;gt;:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
&amp;lt;GenericDataSection LogType=&amp;quot;file&amp;quot; LogFile=&amp;quot;C:\Projects\MultiTierLinqToSql_release\test.txt&amp;quot; DeleteExistingFile=&amp;quot;true&amp;quot;/&amp;gt;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;The first of these lines just declares the second line which is the one that contains the interesting stuff.&lt;br /&gt;There are 3 config options in this section:&lt;br /&gt;&lt;ol&gt;
&lt;li&gt;LogType - this can be either 'file' (logs output to a file), 'debug' (logs output to Systems.Diagnostics.Debug) or 'none' (switches logging off). &lt;/li&gt;&lt;li&gt;LogFile - only applies when LogType is set to 'file', and the default is 'log.txt' it specifies the name of the file to use for logging.&lt;/li&gt;&lt;li&gt;DeleteExistingFile - only applies when LogType is set to 'file', values can be 'true' or 'false', and the default is true. When this is set to true the file will be overwritten every time a new DataContext is created, effectively once per request. If set to false then all output is appended to the end of the file. This can result in a very large log files so be careful.&lt;/li&gt;
&lt;/ol&gt;&lt;h4&gt;
Notes
&lt;/h4&gt;As with all file logging this can be pretty detrimental to performance and so should not be left on in production.&lt;br /&gt; &lt;br /&gt;To handle the logging to the output window I have used the DebuggerWriter class described here: &lt;a href="http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11" class="externalLink"&gt;http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Error Handling
&lt;/h2&gt;Best practice for managing business rules relating to data integrity with Linq to Sql is to include these rules in partial methods in the entity classes and throw exceptions when they are violated (see http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx for more details).&lt;br /&gt;When using this strategy with an ObjectDataSource, you can then catch these exceptions in the OnUpdated or OnInserted events of your ObjectDataSource and present the information to the user. &lt;br /&gt;To do so you set the OnUpdated and/or the OnInserted attribute of your GenericObjectDatasource:&lt;br /&gt;&lt;pre&gt;
OnUpdated=&amp;quot;ProductDataSource_Updated&amp;quot;
OnInserted=&amp;quot;ProductDataSource_Updated&amp;quot;
&lt;/pre&gt; &lt;br /&gt;and then handle this event in your code behind:&lt;br /&gt;&lt;pre&gt;
protected void ProductDataSource_Updated(object sender, ObjectDataSourceStatusEventArgs e)
    {
        if (e.Exception != null)
        {
            //litError is a literal control which I want to use to display the error to the user
            litError.Text = e.Exception.Message;
            //This tells the objectDataSource that I have handled the error and not to throw it
            e.ExceptionHandled = true;
        }
    }
&lt;/pre&gt; &lt;br /&gt;There is an example of this in the Default.aspx page in the test website.&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
DataLoadOptions
&lt;/h2&gt;As has been widely noted, the way that Linq to Sql works, means that the DataLoadOptions for your DataContext need to be set &lt;i&gt;before&lt;/i&gt; any operations are carried out, and cannot subsequently be changed. This means that in my Asp.Net application I will need to set the DataLoadOptions for the whole request somewhere near the start (assuming of course that I need to set DataLoadOptions at all). It also means that my UI or business layer will need to take responsibility for this. &lt;br /&gt; &lt;br /&gt;What this means in practice is that in a classic Web forms type app I will probably set the DataLoadOptions in the OnInit event of my page, if I'm using MVC then my controller will do it. &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
The code
&lt;/h2&gt;The code consists of 4 projects; GenericDataLayer, which contains the reusable code and 3 demo/test projects&lt;br /&gt;&lt;h3&gt;
GenericDataLayer
&lt;/h3&gt;This project contains all of the code you need to use this solution, it can be compiled and referenced in your projects or run as a project within your solutions.&lt;br /&gt;It is made up of:&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;GenericController class - the main class which implements the generic CRUD methods as discussed above&lt;/li&gt;&lt;li&gt;GenericObjectDataSource - the custom ObjectDataSource to use in your aspx pages as discussed above. This control also uses the classes GenericObjectDataSourceView and ExposedSr&lt;/li&gt;&lt;li&gt;FileLogger and DebuggerWriter - classes for logging to text files and System.Debug.Out, see Logging section&lt;/li&gt;&lt;li&gt;GenericDataSection - a class to handle configuration data&lt;/li&gt;&lt;li&gt;Dynamic - some code to help in the sorting methods &lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;&lt;h3&gt;
NorthWindDataLayer
&lt;/h3&gt;This project is an example of how to use the code with your database (using Microsoft's NorthWind database), it references the GenericController project and contains all the project specific database classes that your application needs to work with. These are:&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;Linq to Sql dbml file - In this case pointing to the NorthWind database&lt;/li&gt;&lt;li&gt;Partial Entity classes which implements a custom data validation rules (see section on Error Handling) - In this project there is just one class Product which implements one rule &lt;/li&gt;&lt;li&gt;Concrete Controller classes which inherit from GenericController and implement custom data access code for specific database entities - This project has two, ProductController and CategoryController &lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;&lt;h3&gt;
A test web project
&lt;/h3&gt;This project has one page with a GridView and a FormView which use the data layer via GenericObjectDataSources to list all the products in the Northwind database, allow editing and deletion of those projects, and insert new products via the FormView. &lt;br /&gt; &lt;br /&gt;&lt;h3&gt;
A console app
&lt;/h3&gt;To test functionality outside the context of a web application &lt;br /&gt; &lt;br /&gt;To run the example project:&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;Download and unzip the release &lt;/li&gt;&lt;li&gt;Open the solution in VS2008&lt;/li&gt;&lt;li&gt;Change the connection string in the web.config to point to a Northwind database&lt;/li&gt;&lt;li&gt;Run the web project&lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;To use the code in your own projects&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;Create a class library to contain your Linq to Sql classes, partial entities and concrete repositories&lt;/li&gt;&lt;li&gt;Reference the GenericDataLayer project (either compiled or within your solution)&lt;/li&gt;&lt;li&gt;Create one entity repository class for each Linq to Sql entity, inheriting from Genericrepository&lt;/li&gt;&lt;li&gt;Optionally define any new entity specific data access operations in your entity repository classes&lt;/li&gt;&lt;li&gt;Make use of the GenericObjectDataSource to get easy inserts, updates, deletes, sorting and paging&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;</description><author>rbates</author><pubDate>Thu, 09 Apr 2009 15:02:01 GMT</pubDate><guid isPermaLink="false">Updated Wiki: Home 20090409030201P</guid></item><item><title>Updated Wiki: Home</title><link>http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=Home&amp;version=11</link><description>&lt;div class="wikidoc"&gt;
&lt;h1&gt;
Multi tier architecture for Linq to Sql
&lt;/h1&gt;&lt;h2&gt;
Introduction
&lt;/h2&gt;This resource shows an approach for using Linq to Sql within a multi tier Asp.Net application, and particularly how it can be made to work well with ObjectDataSources. It is here as a discussion piece as well as a usable bit of code.&lt;br /&gt; &lt;br /&gt;The key features are a Request-scoped datacontext and entity repository classes which provide easy to use Create, Retrieve, Update and Delete (CRUD) operations implemented with Generics. Also included is a T4 template for auto generation of repositories from a dbml file. &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Entity Repository classes
&lt;/h2&gt;Each database entity has an associated repository class which is used to perform common CRUD operations. Specific entity controllers inherit from a generic class &lt;i&gt;GenericController&lt;/i&gt; which already implements all the basic Select, Insert, Update &amp;amp; Delete operations.&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
[System.ComponentModel.DataObject]
public class GenericController&amp;lt;TEntity, TDataContext&amp;gt; where TDataContext : DataContext
{
    public static List&amp;lt;TEntity&amp;gt; SelectAll()
    {
          ...
    }
    public static void Insert(TEntity entity)
    {
        ...
    }
    public static void Update(TEntity entity)
    {
        ...
    }
    public static void Delete(TEntity entity)
    {
        ...
    }
}
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;Specific repositories then inherit from this by specifying the entity type which they are concerned with as well as the type of the DataContext used, as follows:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
//ProductController class
public class ProductController : GenericController&amp;lt;Product, NorthwindDataContext&amp;gt;
{
}
&lt;/pre&gt; &lt;br /&gt;which allows client code such as the following:&lt;br /&gt;&lt;pre&gt;
   IList&amp;lt;Product&amp;gt; products = ProductController.SelectAll();
&lt;/pre&gt; &lt;br /&gt;The use of Generics means that I don't need to add any code at all into my ProductController to get all the standard CRUD operations in a fully type safe way. My ProductController class can now be customised to add any further data access methods which are specific to Products, for instance GetByCategoryId().&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Request scoped DataContext
&lt;/h2&gt;The second part of this solution is the request scoped DataContext. This is a pattern that is commonly used with the Hibernate OR mapper as well as elsewhere, and it means that there is only ever one DataContext per Http request which is stored in the HttpContext.Items collection. It is implemented as a protected property of the GenericController class as follows:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
        protected static TDataContext DataContext
        {
            get
            {
                //We are in a web app, use a request scope
                if (HttpContext.Current != null)
                {
                    TDataContext dataContext = (TDataContext)HttpContext.Current.Items[DataContextKey];
                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        HttpContext.Current.Items.Add(DataContextKey, dataContext);
                    }
                    return dataContext;
                }
                else
                {
 
                    // Creates a Thread Scoped DataContext object that can be reused. 
                    // The DataContext is stored in Thread local storage.
                    // See here http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=361
                    //for a discussion of this code.
 
                    LocalDataStoreSlot threadData = Thread.GetNamedDataSlot(DataContextKey);
                    object dataContext = null;
 
                    if (threadData != null)
                        dataContext = Thread.GetData(threadData);
 
                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        if(threadData == null)
                            threadData = Thread.AllocateNamedDataSlot(DataContextKey);
 
                        Thread.SetData(threadData, dataContext);
                    }
                    return (TDataContext) dataContext;
                }
 
            }
        }
&lt;/pre&gt; &lt;br /&gt;As you can see from the code above it handles being used outside a web app by storing the DataContext in a named data slot on the thread it is running in.&lt;br /&gt; &lt;br /&gt;The usefulness of this approach can be seen if you consider a page which uses a number of ObjectDataSources; if we configure our ObjectDataSource to use the DataContext directly then each one will create and dispose of a new DataContext this will not only quickly become a performance overhead, but will also present us with a problem when specifying LoadOptions for the DataContext resulting in more complex, less maintainable code or quite possibly code which doesn't specify loading options at all.&lt;br /&gt; &lt;br /&gt;It should be noted that this approach means that if I have a CategoryController class as well as a ProductController class, both of which inherit from GenericController, both of these classes will use the same DataContext. In other words the DataContext is shared across the whole request, not just by one class type.&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Custom ObjectDataSource
&lt;/h2&gt;In order for updates to work correctly with databinding it is advisable to use the GenericObjectDataSource control which is included in the DataLayer project. An ordinary ObjectDataSource control will create a new object before doing updates and if there are any unbound properties on this object, they will be left with their default values which will then be saved to the database, the GenericObjectDataSource control gets round this by retrieving the original values from the database, before updating them. For more discussions of the details behind this, see &lt;a href="https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488" class="externalLink"&gt;https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Submitting changes
&lt;/h2&gt;Another feature of the Linq to Sql architecture is the way that changes are only submitted to the database when the SubmitChanges() method is called on the DataContext. This means that we must either decide at which point to call SubmitChanges() or delegate this responsibility to client code.&lt;br /&gt;To make the classes as flexible as possible any operations which require a call to SubmitChanges (Insert, Update and Delete), are provided with a boolean parameter which specify whether to submit changes immediately or not. There is also an overload of these methods without this parameter which is equivalent to passing true (again this makes use of ObjectDatasources much more straightforward).&lt;br /&gt;The SubmitChanges method of the DataContext is also exposed through the controller class to give Client code the ability to call this explicitly.&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Sorting and Paging with GridViews
&lt;/h2&gt;There are a number of methods on the GenericController class to automatically support paging and sorting in GridViews.&lt;br /&gt;These are:&lt;br /&gt;&lt;pre&gt;
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(int maximumRows, int startRowIndex)
        {
            ...
        }
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression)
        {
         ...
        }
     
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression, int maximumRows, int startRowIndex)
        {
            ...
        }
        public static int Count()
        {
            ...
        }
&lt;/pre&gt; &lt;br /&gt;To use this functionality all you need to do is turn it on in the ObjectDataSource and GridView with the following attributes:&lt;br /&gt;ObjectDataSource: &lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
EnablePaging=&amp;quot;true&amp;quot; SelectCountMethod=&amp;quot;Count&amp;quot; SortParameterName=&amp;quot;sortExpression&amp;quot;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;Gridview:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
AllowPaging=&amp;quot;true&amp;quot; AllowSorting=&amp;quot;true&amp;quot;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;And hey presto it just works! This makes it really easy to create sortable, pagable GridViews with no extra coding.&lt;br /&gt; &lt;br /&gt;&lt;i&gt;This release also includes some code from Scott Gu's blog to support Dynamic Querying, see &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx" class="externalLink"&gt;http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; for more details&lt;/i&gt;&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
T4 Template
&lt;/h2&gt;Included in the source code is a &lt;a href="T4%20template%20:%20http://www.google.co.uk/search?hl=en&amp;amp;q=t4+templates&amp;amp;btnG=Google+Search&amp;amp;meta=&amp;amp;aq=0&amp;amp;oq=t4+tem" class="externalLink"&gt;T4 template : http://www.google.co.uk/search?hl=en&amp;amp;q=t4+templates&amp;amp;btnG=Google+Search&amp;amp;meta=&amp;amp;aq=0&amp;amp;oq=t4+tem&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; which will generate entities and concrete repositories (both static and non-static) with interfaces to facilitate testing. To use it you need to do the following&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;copy the files DataClasses.tt and L2ST4.ttinclude from the T4Templates directory into your project specific datalayer project&lt;/li&gt;&lt;li&gt;ensure that DataClasses.tt has the same name as the dbml file (so in the example Northwind project DataClasses.tt has been renamed to Northwind.tt to match Northwind.dbml)&lt;/li&gt;&lt;li&gt;to generate the classes, open DataClasses.tt (or whatever it is now called) and save it. You will probably get a dialog box asking if you are sure you  want to do this, click Ok. All the classes will then be generated in a file called &lt;a href="http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=DataClasses&amp;amp;referringTitle=Home"&gt;DataClasses&lt;/a&gt;.generated.cs where &lt;a href="http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=DataClasses&amp;amp;referringTitle=Home"&gt;DataClasses&lt;/a&gt; is whatever you renamed DataClasses.tt to.&lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Logging
&lt;/h2&gt;The code includes an easy way to configure Linq to Sql's logging feature (DataContext.Log) to write to either a text file or the System.Diagnostics.Debugger class which then appears in the output window within Visual Studio.&lt;br /&gt; &lt;br /&gt;To use this functionality you need to add the following lines into your web.config:&lt;br /&gt; &lt;br /&gt;In the &amp;lt;configSections&amp;gt; element:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
&amp;lt;section name=&amp;quot;GenericDataSection&amp;quot; type=&amp;quot;DataLayer.GenericDataSection, DataLayer&amp;quot; allowDefinition=&amp;quot;MachineToApplication&amp;quot; restartOnExternalChanges=&amp;quot;true&amp;quot; requirePermission=&amp;quot;false&amp;quot;/&amp;gt;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;Then directly after &amp;lt;configSections&amp;gt;:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
&amp;lt;GenericDataSection LogType=&amp;quot;file&amp;quot; LogFile=&amp;quot;C:\Projects\MultiTierLinqToSql_release\test.txt&amp;quot; DeleteExistingFile=&amp;quot;true&amp;quot;/&amp;gt;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;The first of these lines just declares the second line which is the one that contains the interesting stuff.&lt;br /&gt;There are 3 config options in this section:&lt;br /&gt;&lt;ol&gt;
&lt;li&gt;LogType - this can be either 'file' (logs output to a file), 'debug' (logs output to Systems.Diagnostics.Debug) or 'none' (switches logging off). &lt;/li&gt;&lt;li&gt;LogFile - only applies when LogType is set to 'file', and the default is 'log.txt' it specifies the name of the file to use for logging.&lt;/li&gt;&lt;li&gt;DeleteExistingFile - only applies when LogType is set to 'file', values can be 'true' or 'false', and the default is true. When this is set to true the file will be overwritten every time a new DataContext is created, effectively once per request. If set to false then all output is appended to the end of the file. This can result in a very large log files so be careful.&lt;/li&gt;
&lt;/ol&gt;&lt;h4&gt;
Notes
&lt;/h4&gt;As with all file logging this can be pretty detrimental to performance and so should not be left on in production.&lt;br /&gt; &lt;br /&gt;To handle the logging to the output window I have used the DebuggerWriter class described here: &lt;a href="http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11" class="externalLink"&gt;http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Error Handling
&lt;/h2&gt;Best practice for managing business rules relating to data integrity with Linq to Sql is to include these rules in partial methods in the entity classes and throw exceptions when they are violated (see http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx for more details).&lt;br /&gt;When using this strategy with an ObjectDataSource, you can then catch these exceptions in the OnUpdated or OnInserted events of your ObjectDataSource and present the information to the user. &lt;br /&gt;To do so you set the OnUpdated and/or the OnInserted attribute of your GenericObjectDatasource:&lt;br /&gt;&lt;pre&gt;
OnUpdated=&amp;quot;ProductDataSource_Updated&amp;quot;
OnInserted=&amp;quot;ProductDataSource_Updated&amp;quot;
&lt;/pre&gt; &lt;br /&gt;and then handle this event in your code behind:&lt;br /&gt;&lt;pre&gt;
protected void ProductDataSource_Updated(object sender, ObjectDataSourceStatusEventArgs e)
    {
        if (e.Exception != null)
        {
            //litError is a literal control which I want to use to display the error to the user
            litError.Text = e.Exception.Message;
            //This tells the objectDataSource that I have handled the error and not to throw it
            e.ExceptionHandled = true;
        }
    }
&lt;/pre&gt; &lt;br /&gt;There is an example of this in the Default.aspx page in the test website.&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
DataLoadOptions
&lt;/h2&gt;As has been widely noted, the way that Linq to Sql works, means that the DataLoadOptions for your DataContext need to be set &lt;i&gt;before&lt;/i&gt; any operations are carried out, and cannot subsequently be changed. This means that in my Asp.Net application I will need to set the DataLoadOptions for the whole request somewhere near the start (assuming of course that I need to set DataLoadOptions at all). It also means that my UI or business layer will need to take responsibility for this. &lt;br /&gt; &lt;br /&gt;What this means in practice is that in a classic Web forms type app I will probably set the DataLoadOptions in the OnInit event of my page, if I'm using MVC then my controller will do it. &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
The code
&lt;/h2&gt;The code consists of 4 projects; GenericDataLayer, which contains the reusable code and 3 demo/test projects&lt;br /&gt;&lt;h3&gt;
GenericDataLayer
&lt;/h3&gt;This project contains all of the code you need to use this solution, it can be compiled and referenced in your projects or run as a project within your solutions.&lt;br /&gt;It is made up of:&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;GenericController class - the main class which implements the generic CRUD methods as discussed above&lt;/li&gt;&lt;li&gt;GenericObjectDataSource - the custom ObjectDataSource to use in your aspx pages as discussed above. This control also uses the classes GenericObjectDataSourceView and ExposedSr&lt;/li&gt;&lt;li&gt;FileLogger and DebuggerWriter - classes for logging to text files and System.Debug.Out, see Logging section&lt;/li&gt;&lt;li&gt;GenericDataSection - a class to handle configuration data&lt;/li&gt;&lt;li&gt;Dynamic - some code to help in the sorting methods &lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;&lt;h3&gt;
NorthWindDataLayer
&lt;/h3&gt;This project is an example of how to use the code with your database (using Microsoft's NorthWind database), it references the GenericController project and contains all the project specific database classes that your application needs to work with. These are:&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;Linq to Sql dbml file - In this case pointing to the NorthWind database&lt;/li&gt;&lt;li&gt;Partial Entity classes which implements a custom data validation rules (see section on Error Handling) - In this project there is just one class Product which implements one rule &lt;/li&gt;&lt;li&gt;Concrete Controller classes which inherit from GenericController and implement custom data access code for specific database entities - This project has two, ProductController and CategoryController &lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;&lt;h3&gt;
A test web project
&lt;/h3&gt;This project has one page with a GridView and a FormView which use the data layer via GenericObjectDataSources to list all the products in the Northwind database, allow editing and deletion of those projects, and insert new products via the FormView. &lt;br /&gt; &lt;br /&gt;&lt;h3&gt;
A console app
&lt;/h3&gt;To test functionality outside the context of a web application &lt;br /&gt; &lt;br /&gt;To run the example project:&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;Download and unzip the release &lt;/li&gt;&lt;li&gt;Open the solution in VS2008&lt;/li&gt;&lt;li&gt;Change the connection string in the web.config to point to a Northwind database&lt;/li&gt;&lt;li&gt;Run the web project&lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;To use the code in your own projects&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;Create a class library to contain your Linq to Sql classes, partial entities and concrete repositories&lt;/li&gt;&lt;li&gt;Reference the GenericDataLayer project (either compiled or within your solution)&lt;/li&gt;&lt;li&gt;Create one entity repository class for each Linq to Sql entity, inheriting from Genericrepository&lt;/li&gt;&lt;li&gt;Optionally define any new entity specific data access operations in your entity repository classes&lt;/li&gt;&lt;li&gt;Make use of the GenericObjectDataSource to get easy inserts, updates, deletes, sorting and paging&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;</description><author>rbates</author><pubDate>Thu, 09 Apr 2009 14:59:45 GMT</pubDate><guid isPermaLink="false">Updated Wiki: Home 20090409025945P</guid></item><item><title>Updated Wiki: Home</title><link>http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=Home&amp;version=10</link><description>&lt;div class="wikidoc"&gt;
&lt;h1&gt;
Multi tier architecture for Linq to Sql
&lt;/h1&gt;&lt;h2&gt;
Introduction
&lt;/h2&gt;This resource shows an approach for using Linq to Sql within a multi tier Asp.Net application, and particularly how it can be made to work well with ObjectDataSources. It is here as a discussion piece as well as a usable bit of code.&lt;br /&gt; &lt;br /&gt;The key features are a Request-scoped datacontext and entity repository classes which provide easy to use Create, Retrieve, Update and Delete (CRUD) operations implemented with Generics. Also included is a T4 template for auto generation of repositories from a dbml file. &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Entity Repository classes
&lt;/h2&gt;Each database entity has an associated repository class which is used to perform common CRUD operations. Specific entity controllers inherit from a generic class &lt;i&gt;GenericController&lt;/i&gt; which already implements all the basic Select, Insert, Update &amp;amp; Delete operations.&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
[System.ComponentModel.DataObject]
public class GenericController&amp;lt;TEntity, TDataContext&amp;gt; where TDataContext : DataContext
{
    public static List&amp;lt;TEntity&amp;gt; SelectAll()
    {
          ...
    }
    public static void Insert(TEntity entity)
    {
        ...
    }
    public static void Update(TEntity entity)
    {
        ...
    }
    public static void Delete(TEntity entity)
    {
        ...
    }
}
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;Specific repositories then inherit from this by specifying the entity type which they are concerned with as well as the type of the DataContext used, as follows:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
//ProductController class
public class ProductController : GenericController&amp;lt;Product, NorthwindDataContext&amp;gt;
{
}
&lt;/pre&gt; &lt;br /&gt;which allows client code such as the following:&lt;br /&gt;&lt;pre&gt;
   IList&amp;lt;Product&amp;gt; products = ProductController.SelectAll();
&lt;/pre&gt; &lt;br /&gt;The use of Generics means that I don't need to add any code at all into my ProductController to get all the standard CRUD operations in a fully type safe way. My ProductController class can now be customised to add any further data access methods which are specific to Products, for instance GetByCategoryId().&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Request scoped DataContext
&lt;/h2&gt;The second part of this solution is the request scoped DataContext. This is a pattern that is commonly used with the Hibernate OR mapper as well as elsewhere, and it means that there is only ever one DataContext per Http request which is stored in the HttpContext.Items collection. It is implemented as a protected property of the GenericController class as follows:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
        protected static TDataContext DataContext
        {
            get
            {
                //We are in a web app, use a request scope
                if (HttpContext.Current != null)
                {
                    TDataContext dataContext = (TDataContext)HttpContext.Current.Items[DataContextKey];
                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        HttpContext.Current.Items.Add(DataContextKey, dataContext);
                    }
                    return dataContext;
                }
                else
                {
 
                    // Creates a Thread Scoped DataContext object that can be reused. 
                    // The DataContext is stored in Thread local storage.
                    // See here http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=361
                    //for a discussion of this code.
 
                    LocalDataStoreSlot threadData = Thread.GetNamedDataSlot(DataContextKey);
                    object dataContext = null;
 
                    if (threadData != null)
                        dataContext = Thread.GetData(threadData);
 
                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        if(threadData == null)
                            threadData = Thread.AllocateNamedDataSlot(DataContextKey);
 
                        Thread.SetData(threadData, dataContext);
                    }
                    return (TDataContext) dataContext;
                }
 
            }
        }
&lt;/pre&gt; &lt;br /&gt;As you can see from the code above it handles being used outside a web app by storing the DataContext in a named data slot on the thread it is running in.&lt;br /&gt; &lt;br /&gt;The usefulness of this approach can be seen if you consider a page which uses a number of ObjectDataSources; if we configure our ObjectDataSource to use the DataContext directly then each one will create and dispose of a new DataContext this will not only quickly become a performance overhead, but will also present us with a problem when specifying LoadOptions for the DataContext resulting in more complex, less maintainable code or quite possibly code which doesn't specify loading options at all.&lt;br /&gt; &lt;br /&gt;It should be noted that this approach means that if I have a CategoryController class as well as a ProductController class, both of which inherit from GenericController, both of these classes will use the same DataContext. In other words the DataContext is shared across the whole request, not just by one class type.&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Custom ObjectDataSource
&lt;/h2&gt;In order for updates to work correctly with databinding it is advisable to use the GenericObjectDataSource control which is included in the DataLayer project. An ordinary ObjectDataSource control will create a new object before doing updates and if there are any unbound properties on this object, they will be left with their default values which will then be saved to the database, the GenericObjectDataSource control gets round this by retrieving the original values from the database, before updating them. For more discussions of the details behind this, see &lt;a href="https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488" class="externalLink"&gt;https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Submitting changes
&lt;/h2&gt;Another feature of the Linq to Sql architecture is the way that changes are only submitted to the database when the SubmitChanges() method is called on the DataContext. This means that we must either decide at which point to call SubmitChanges() or delegate this responsibility to client code.&lt;br /&gt;To make the classes as flexible as possible any operations which require a call to SubmitChanges (Insert, Update and Delete), are provided with a boolean parameter which specify whether to submit changes immediately or not. There is also an overload of these methods without this parameter which is equivalent to passing true (again this makes use of ObjectDatasources much more straightforward).&lt;br /&gt;The SubmitChanges method of the DataContext is also exposed through the controller class to give Client code the ability to call this explicitly.&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Sorting and Paging with GridViews
&lt;/h2&gt;There are a number of methods on the GenericController class to automatically support paging and sorting in GridViews.&lt;br /&gt;These are:&lt;br /&gt;&lt;pre&gt;
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(int maximumRows, int startRowIndex)
        {
            ...
        }
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression)
        {
         ...
        }
     
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression, int maximumRows, int startRowIndex)
        {
            ...
        }
        public static int Count()
        {
            ...
        }
&lt;/pre&gt; &lt;br /&gt;To use this functionality all you need to do is turn it on in the ObjectDataSource and GridView with the following attributes:&lt;br /&gt;ObjectDataSource: &lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
EnablePaging=&amp;quot;true&amp;quot; SelectCountMethod=&amp;quot;Count&amp;quot; SortParameterName=&amp;quot;sortExpression&amp;quot;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;Gridview:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
AllowPaging=&amp;quot;true&amp;quot; AllowSorting=&amp;quot;true&amp;quot;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;And hey presto it just works! This makes it really easy to create sortable, pagable GridViews with no extra coding.&lt;br /&gt; &lt;br /&gt;&lt;i&gt;This release also includes some code from Scott Gu's blog to support Dynamic Querying, see &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx" class="externalLink"&gt;http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; for more details&lt;/i&gt;&lt;br /&gt; &lt;br /&gt;!!T4 Template&lt;br /&gt;Included in the source code is a &lt;a href="T4%20template:http://www.google.co.uk/search?hl=en&amp;amp;q=t4+templates&amp;amp;btnG=Google+Search&amp;amp;meta=&amp;amp;aq=0&amp;amp;oq=t4+tem" class="externalLink"&gt;T4 template:http://www.google.co.uk/search?hl=en&amp;amp;q=t4+templates&amp;amp;btnG=Google+Search&amp;amp;meta=&amp;amp;aq=0&amp;amp;oq=t4+tem&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; which will generate entities and concrete repositories (both static and non-static) with interfaces to facilitate testing. To use it you need to copy the files DataClasses.tt and L2ST4.ttinclude from the T4Templates directory into your project specific datalayer project, ensure that DataClasses.tt has the same name as the dbml file (so in the example Northwind project DataClasses.tt has been renamed to Northwind.tt to match Northwind.dbml)&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Logging
&lt;/h2&gt;The code includes an easy way to configure Linq to Sql's logging feature (DataContext.Log) to write to either a text file or the System.Diagnostics.Debugger class which then appears in the output window within Visual Studio.&lt;br /&gt; &lt;br /&gt;To use this functionality you need to add the following lines into your web.config:&lt;br /&gt; &lt;br /&gt;In the &amp;lt;configSections&amp;gt; element:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
&amp;lt;section name=&amp;quot;GenericDataSection&amp;quot; type=&amp;quot;DataLayer.GenericDataSection, DataLayer&amp;quot; allowDefinition=&amp;quot;MachineToApplication&amp;quot; restartOnExternalChanges=&amp;quot;true&amp;quot; requirePermission=&amp;quot;false&amp;quot;/&amp;gt;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;Then directly after &amp;lt;configSections&amp;gt;:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
&amp;lt;GenericDataSection LogType=&amp;quot;file&amp;quot; LogFile=&amp;quot;C:\Projects\MultiTierLinqToSql_release\test.txt&amp;quot; DeleteExistingFile=&amp;quot;true&amp;quot;/&amp;gt;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;The first of these lines just declares the second line which is the one that contains the interesting stuff.&lt;br /&gt;There are 3 config options in this section:&lt;br /&gt;&lt;ol&gt;
&lt;li&gt;LogType - this can be either 'file' (logs output to a file), 'debug' (logs output to Systems.Diagnostics.Debug) or 'none' (switches logging off). &lt;/li&gt;&lt;li&gt;LogFile - only applies when LogType is set to 'file', and the default is 'log.txt' it specifies the name of the file to use for logging.&lt;/li&gt;&lt;li&gt;DeleteExistingFile - only applies when LogType is set to 'file', values can be 'true' or 'false', and the default is true. When this is set to true the file will be overwritten every time a new DataContext is created, effectively once per request. If set to false then all output is appended to the end of the file. This can result in a very large log files so be careful.&lt;/li&gt;
&lt;/ol&gt;&lt;h4&gt;
Notes
&lt;/h4&gt;As with all file logging this can be pretty detrimental to performance and so should not be left on in production.&lt;br /&gt; &lt;br /&gt;To handle the logging to the output window I have used the DebuggerWriter class described here: &lt;a href="http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11" class="externalLink"&gt;http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Error Handling
&lt;/h2&gt;Best practice for managing business rules relating to data integrity with Linq to Sql is to include these rules in partial methods in the entity classes and throw exceptions when they are violated (see http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx for more details).&lt;br /&gt;When using this strategy with an ObjectDataSource, you can then catch these exceptions in the OnUpdated or OnInserted events of your ObjectDataSource and present the information to the user. &lt;br /&gt;To do so you set the OnUpdated and/or the OnInserted attribute of your GenericObjectDatasource:&lt;br /&gt;&lt;pre&gt;
OnUpdated=&amp;quot;ProductDataSource_Updated&amp;quot;
OnInserted=&amp;quot;ProductDataSource_Updated&amp;quot;
&lt;/pre&gt; &lt;br /&gt;and then handle this event in your code behind:&lt;br /&gt;&lt;pre&gt;
protected void ProductDataSource_Updated(object sender, ObjectDataSourceStatusEventArgs e)
    {
        if (e.Exception != null)
        {
            //litError is a literal control which I want to use to display the error to the user
            litError.Text = e.Exception.Message;
            //This tells the objectDataSource that I have handled the error and not to throw it
            e.ExceptionHandled = true;
        }
    }
&lt;/pre&gt; &lt;br /&gt;There is an example of this in the Default.aspx page in the test website.&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
DataLoadOptions
&lt;/h2&gt;As has been widely noted, the way that Linq to Sql works, means that the DataLoadOptions for your DataContext need to be set &lt;i&gt;before&lt;/i&gt; any operations are carried out, and cannot subsequently be changed. This means that in my Asp.Net application I will need to set the DataLoadOptions for the whole request somewhere near the start (assuming of course that I need to set DataLoadOptions at all). It also means that my UI or business layer will need to take responsibility for this. &lt;br /&gt; &lt;br /&gt;What this means in practice is that in a classic Web forms type app I will probably set the DataLoadOptions in the OnInit event of my page, if I'm using MVC then my controller will do it. &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
The code
&lt;/h2&gt;The code consists of 4 projects; GenericDataLayer, which contains the reusable code and 3 demo/test projects&lt;br /&gt;&lt;h3&gt;
GenericDataLayer
&lt;/h3&gt;This project contains all of the code you need to use this solution, it can be compiled and referenced in your projects or run as a project within your solutions.&lt;br /&gt;It is made up of:&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;GenericController class - the main class which implements the generic CRUD methods as discussed above&lt;/li&gt;&lt;li&gt;GenericObjectDataSource - the custom ObjectDataSource to use in your aspx pages as discussed above. This control also uses the classes GenericObjectDataSourceView and ExposedSr&lt;/li&gt;&lt;li&gt;FileLogger and DebuggerWriter - classes for logging to text files and System.Debug.Out, see Logging section&lt;/li&gt;&lt;li&gt;GenericDataSection - a class to handle configuration data&lt;/li&gt;&lt;li&gt;Dynamic - some code to help in the sorting methods &lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;&lt;h3&gt;
NorthWindDataLayer
&lt;/h3&gt;This project is an example of how to use the code with your database (using Microsoft's NorthWind database), it references the GenericController project and contains all the project specific database classes that your application needs to work with. These are:&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;Linq to Sql dbml file - In this case pointing to the NorthWind database&lt;/li&gt;&lt;li&gt;Partial Entity classes which implements a custom data validation rules (see section on Error Handling) - In this project there is just one class Product which implements one rule &lt;/li&gt;&lt;li&gt;Concrete Controller classes which inherit from GenericController and implement custom data access code for specific database entities - This project has two, ProductController and CategoryController &lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;&lt;h3&gt;
A test web project
&lt;/h3&gt;This project has one page with a GridView and a FormView which use the data layer via GenericObjectDataSources to list all the products in the Northwind database, allow editing and deletion of those projects, and insert new products via the FormView. &lt;br /&gt; &lt;br /&gt;&lt;h3&gt;
A console app
&lt;/h3&gt;To test functionality outside the context of a web application &lt;br /&gt; &lt;br /&gt;To run the example project:&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;Download and unzip the release &lt;/li&gt;&lt;li&gt;Open the solution in VS2008&lt;/li&gt;&lt;li&gt;Change the connection string in the web.config to point to a Northwind database&lt;/li&gt;&lt;li&gt;Run the web project&lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;To use the code in your own projects&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;Create a class library to contain your Linq to Sql classes, partial entities and concrete repositories&lt;/li&gt;&lt;li&gt;Reference the GenericDataLayer project (either compiled or within your solution)&lt;/li&gt;&lt;li&gt;Create one entity repository class for each Linq to Sql entity, inheriting from Genericrepository&lt;/li&gt;&lt;li&gt;Optionally define any new entity specific data access operations in your entity repository classes&lt;/li&gt;&lt;li&gt;Make use of the GenericObjectDataSource to get easy inserts, updates, deletes, sorting and paging&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;</description><author>rbates</author><pubDate>Thu, 09 Apr 2009 14:52:41 GMT</pubDate><guid isPermaLink="false">Updated Wiki: Home 20090409025241P</guid></item><item><title>Updated Wiki: Home</title><link>http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=Home&amp;version=9</link><description>&lt;div class="wikidoc"&gt;
&lt;h1&gt;
Multi tier architecture for Linq to Sql
&lt;/h1&gt;&lt;h2&gt;
Introduction
&lt;/h2&gt;This resource shows an approach for using Linq to Sql within a multi tier Asp.Net application, and particularly how it can be made to work well with ObjectDataSources. It is here as a discussion piece as well as a usable bit of code.&lt;br /&gt; &lt;br /&gt;The key features are a Request-scoped datacontext and entity repository classes which provide easy to use Create, Retrieve, Update and Delete (CRUD) operations implemented with Generics. Also included is a T4 template for auto generation of repositories from a dbml file. &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Entity Repository classes
&lt;/h2&gt;Each database entity has an associated repository class which is used to perform common CRUD operations. Specific entity controllers inherit from a generic class &lt;i&gt;GenericController&lt;/i&gt; which already implements all the basic Select, Insert, Update &amp;amp; Delete operations.&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
[System.ComponentModel.DataObject]
public class GenericController&amp;lt;TEntity, TDataContext&amp;gt; where TDataContext : DataContext
{
    public static List&amp;lt;TEntity&amp;gt; SelectAll()
    {
          ...
    }
    public static void Insert(TEntity entity)
    {
        ...
    }
    public static void Update(TEntity entity)
    {
        ...
    }
    public static void Delete(TEntity entity)
    {
        ...
    }
}
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;Specific repositories then inherit from this by specifying the entity type which they are concerned with as well as the type of the DataContext used, as follows:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
//ProductController class
public class ProductController : GenericController&amp;lt;Product, NorthwindDataContext&amp;gt;
{
}
&lt;/pre&gt; &lt;br /&gt;which allows client code such as the following:&lt;br /&gt;&lt;pre&gt;
   IList&amp;lt;Product&amp;gt; products = ProductController.SelectAll();
&lt;/pre&gt; &lt;br /&gt;The use of Generics means that I don't need to add any code at all into my ProductController to get all the standard CRUD operations in a fully type safe way. My ProductController class can now be customised to add any further data access methods which are specific to Products, for instance GetByCategoryId().&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Request scoped DataContext
&lt;/h2&gt;The second part of this solution is the request scoped DataContext. This is a pattern that is commonly used with the Hibernate OR mapper as well as elsewhere, and it means that there is only ever one DataContext per Http request which is stored in the HttpContext.Items collection. It is implemented as a protected property of the GenericController class as follows:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
        protected static TDataContext DataContext
        {
            get
            {
                //We are in a web app, use a request scope
                if (HttpContext.Current != null)
                {
                    TDataContext dataContext = (TDataContext)HttpContext.Current.Items[DataContextKey];
                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        HttpContext.Current.Items.Add(DataContextKey, dataContext);
                    }
                    return dataContext;
                }
                else
                {
 
                    // Creates a Thread Scoped DataContext object that can be reused. 
                    // The DataContext is stored in Thread local storage.
                    // See here http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=361
                    //for a discussion of this code.
 
                    LocalDataStoreSlot threadData = Thread.GetNamedDataSlot(DataContextKey);
                    object dataContext = null;
 
                    if (threadData != null)
                        dataContext = Thread.GetData(threadData);
 
                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        if(threadData == null)
                            threadData = Thread.AllocateNamedDataSlot(DataContextKey);
 
                        Thread.SetData(threadData, dataContext);
                    }
                    return (TDataContext) dataContext;
                }
 
            }
        }
&lt;/pre&gt; &lt;br /&gt;As you can see from the code above it handles being used outside a web app by storing the DataContext in a named data slot on the thread it is running in.&lt;br /&gt; &lt;br /&gt;The usefulness of this approach can be seen if you consider a page which uses a number of ObjectDataSources; if we configure our ObjectDataSource to use the DataContext directly then each one will create and dispose of a new DataContext this will not only quickly become a performance overhead, but will also present us with a problem when specifying LoadOptions for the DataContext resulting in more complex, less maintainable code or quite possibly code which doesn't specify loading options at all.&lt;br /&gt; &lt;br /&gt;It should be noted that this approach means that if I have a CategoryController class as well as a ProductController class, both of which inherit from GenericController, both of these classes will use the same DataContext. In other words the DataContext is shared across the whole request, not just by one class type.&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Custom ObjectDataSource
&lt;/h2&gt;In order for updates to work correctly with databinding it is advisable to use the GenericObjectDataSource control which is included in the DataLayer project. An ordinary ObjectDataSource control will create a new object before doing updates and if there are any unbound properties on this object, they will be left with their default values which will then be saved to the database, the GenericObjectDataSource control gets round this by retrieving the original values from the database, before updating them. For more discussions of the details behind this, see &lt;a href="https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488" class="externalLink"&gt;https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Submitting changes
&lt;/h2&gt;Another feature of the Linq to Sql architecture is the way that changes are only submitted to the database when the SubmitChanges() method is called on the DataContext. This means that we must either decide at which point to call SubmitChanges() or delegate this responsibility to client code.&lt;br /&gt;To make the classes as flexible as possible any operations which require a call to SubmitChanges (Insert, Update and Delete), are provided with a boolean parameter which specify whether to submit changes immediately or not. There is also an overload of these methods without this parameter which is equivalent to passing true (again this makes use of ObjectDatasources much more straightforward).&lt;br /&gt;The SubmitChanges method of the DataContext is also exposed through the controller class to give Client code the ability to call this explicitly.&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Sorting and Paging with GridViews
&lt;/h2&gt;There are a number of methods on the GenericController class to automatically support paging and sorting in GridViews.&lt;br /&gt;These are:&lt;br /&gt;&lt;pre&gt;
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(int maximumRows, int startRowIndex)
        {
            ...
        }
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression)
        {
         ...
        }
     
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression, int maximumRows, int startRowIndex)
        {
            ...
        }
        public static int Count()
        {
            ...
        }
&lt;/pre&gt; &lt;br /&gt;To use this functionality all you need to do is turn it on in the ObjectDataSource and GridView with the following attributes:&lt;br /&gt;ObjectDataSource: &lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
EnablePaging=&amp;quot;true&amp;quot; SelectCountMethod=&amp;quot;Count&amp;quot; SortParameterName=&amp;quot;sortExpression&amp;quot;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;Gridview:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
AllowPaging=&amp;quot;true&amp;quot; AllowSorting=&amp;quot;true&amp;quot;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;And hey presto it just works! This makes it really easy to create sortable, pagable GridViews with no extra coding.&lt;br /&gt; &lt;br /&gt;&lt;i&gt;This release also includes some code from Scott Gu's blog to support Dynamic Querying, see &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx" class="externalLink"&gt;http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; for more details&lt;/i&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Logging
&lt;/h2&gt;The code includes an easy way to configure Linq to Sql's logging feature (DataContext.Log) to write to either a text file or the System.Diagnostics.Debugger class which then appears in the output window within Visual Studio.&lt;br /&gt; &lt;br /&gt;To use this functionality you need to add the following lines into your web.config:&lt;br /&gt; &lt;br /&gt;In the &amp;lt;configSections&amp;gt; element:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
&amp;lt;section name=&amp;quot;GenericDataSection&amp;quot; type=&amp;quot;DataLayer.GenericDataSection, DataLayer&amp;quot; allowDefinition=&amp;quot;MachineToApplication&amp;quot; restartOnExternalChanges=&amp;quot;true&amp;quot; requirePermission=&amp;quot;false&amp;quot;/&amp;gt;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;Then directly after &amp;lt;configSections&amp;gt;:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
&amp;lt;GenericDataSection LogType=&amp;quot;file&amp;quot; LogFile=&amp;quot;C:\Projects\MultiTierLinqToSql_release\test.txt&amp;quot; DeleteExistingFile=&amp;quot;true&amp;quot;/&amp;gt;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;The first of these lines just declares the second line which is the one that contains the interesting stuff.&lt;br /&gt;There are 3 config options in this section:&lt;br /&gt;&lt;ol&gt;
&lt;li&gt;LogType - this can be either 'file' (logs output to a file), 'debug' (logs output to Systems.Diagnostics.Debug) or 'none' (switches logging off). &lt;/li&gt;&lt;li&gt;LogFile - only applies when LogType is set to 'file', and the default is 'log.txt' it specifies the name of the file to use for logging.&lt;/li&gt;&lt;li&gt;DeleteExistingFile - only applies when LogType is set to 'file', values can be 'true' or 'false', and the default is true. When this is set to true the file will be overwritten every time a new DataContext is created, effectively once per request. If set to false then all output is appended to the end of the file. This can result in a very large log files so be careful.&lt;/li&gt;
&lt;/ol&gt;&lt;h4&gt;
Notes
&lt;/h4&gt;As with all file logging this can be pretty detrimental to performance and so should not be left on in production.&lt;br /&gt; &lt;br /&gt;To handle the logging to the output window I have used the DebuggerWriter class described here: &lt;a href="http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11" class="externalLink"&gt;http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Error Handling
&lt;/h2&gt;Best practice for managing business rules relating to data integrity with Linq to Sql is to include these rules in partial methods in the entity classes and throw exceptions when they are violated (see http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx for more details).&lt;br /&gt;When using this strategy with an ObjectDataSource, you can then catch these exceptions in the OnUpdated or OnInserted events of your ObjectDataSource and present the information to the user. &lt;br /&gt;To do so you set the OnUpdated and/or the OnInserted attribute of your GenericObjectDatasource:&lt;br /&gt;&lt;pre&gt;
OnUpdated=&amp;quot;ProductDataSource_Updated&amp;quot;
OnInserted=&amp;quot;ProductDataSource_Updated&amp;quot;
&lt;/pre&gt; &lt;br /&gt;and then handle this event in your code behind:&lt;br /&gt;&lt;pre&gt;
protected void ProductDataSource_Updated(object sender, ObjectDataSourceStatusEventArgs e)
    {
        if (e.Exception != null)
        {
            //litError is a literal control which I want to use to display the error to the user
            litError.Text = e.Exception.Message;
            //This tells the objectDataSource that I have handled the error and not to throw it
            e.ExceptionHandled = true;
        }
    }
&lt;/pre&gt; &lt;br /&gt;There is an example of this in the Default.aspx page in the test website.&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
DataLoadOptions
&lt;/h2&gt;As has been widely noted, the way that Linq to Sql works, means that the DataLoadOptions for your DataContext need to be set &lt;i&gt;before&lt;/i&gt; any operations are carried out, and cannot subsequently be changed. This means that in my Asp.Net application I will need to set the DataLoadOptions for the whole request somewhere near the start (assuming of course that I need to set DataLoadOptions at all). It also means that my UI or business layer will need to take responsibility for this. &lt;br /&gt; &lt;br /&gt;What this means in practice is that in a classic Web forms type app I will probably set the DataLoadOptions in the OnInit event of my page, if I'm using MVC then my controller will do it. &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
The code
&lt;/h2&gt;The code consists of 4 projects; GenericDataLayer, which contains the reusable code and 3 demo/test projects&lt;br /&gt;&lt;h3&gt;
GenericDataLayer
&lt;/h3&gt;This project contains all of the code you need to use this solution, it can be compiled and referenced in your projects or run as a project within your solutions.&lt;br /&gt;It is made up of:&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;GenericController class - the main class which implements the generic CRUD methods as discussed above&lt;/li&gt;&lt;li&gt;GenericObjectDataSource - the custom ObjectDataSource to use in your aspx pages as discussed above. This control also uses the classes GenericObjectDataSourceView and ExposedSr&lt;/li&gt;&lt;li&gt;FileLogger and DebuggerWriter - classes for logging to text files and System.Debug.Out, see Logging section&lt;/li&gt;&lt;li&gt;GenericDataSection - a class to handle configuration data&lt;/li&gt;&lt;li&gt;Dynamic - some code to help in the sorting methods &lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;&lt;h3&gt;
NorthWindDataLayer
&lt;/h3&gt;This project is an example of how to use the code with your database (using Microsoft's NorthWind database), it references the GenericController project and contains all the project specific database classes that your application needs to work with. These are:&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;Linq to Sql dbml file - In this case pointing to the NorthWind database&lt;/li&gt;&lt;li&gt;Partial Entity classes which implements a custom data validation rules (see section on Error Handling) - In this project there is just one class Product which implements one rule &lt;/li&gt;&lt;li&gt;Concrete Controller classes which inherit from GenericController and implement custom data access code for specific database entities - This project has two, ProductController and CategoryController &lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;&lt;h3&gt;
A test web project
&lt;/h3&gt;This project has one page with a GridView and a FormView which use the data layer via GenericObjectDataSources to list all the products in the Northwind database, allow editing and deletion of those projects, and insert new products via the FormView. &lt;br /&gt; &lt;br /&gt;&lt;h3&gt;
A console app
&lt;/h3&gt;To test functionality outside the context of a web application &lt;br /&gt; &lt;br /&gt;To run the example project:&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;Download and unzip the release &lt;/li&gt;&lt;li&gt;Open the solution in VS2008&lt;/li&gt;&lt;li&gt;Change the connection string in the web.config to point to a Northwind database&lt;/li&gt;&lt;li&gt;Run the web project&lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;To use the code in your own projects&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;Create a class library to contain your Linq to Sql classes, partial entities and concrete repositories&lt;/li&gt;&lt;li&gt;Reference the GenericDataLayer project (either compiled or within your solution)&lt;/li&gt;&lt;li&gt;Create one entity repository class for each Linq to Sql entity, inheriting from Genericrepository&lt;/li&gt;&lt;li&gt;Optionally define any new entity specific data access operations in your entity repository classes&lt;/li&gt;&lt;li&gt;Make use of the GenericObjectDataSource to get easy inserts, updates, deletes, sorting and paging&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;</description><author>rbates</author><pubDate>Thu, 09 Apr 2009 14:31:26 GMT</pubDate><guid isPermaLink="false">Updated Wiki: Home 20090409023126P</guid></item><item><title>Updated Wiki: Home</title><link>http://multitierlinqtosql.codeplex.com/Wiki/View.aspx?title=Home&amp;version=8</link><description>&lt;div class="wikidoc"&gt;
&lt;h1&gt;
Multi tier architecture for Linq to Sql
&lt;/h1&gt;&lt;h2&gt;
Introduction
&lt;/h2&gt;This resource shows an approach for using Linq to Sql within a multi tier Asp.Net application, and particularly how it can be made to work well with ObjectDataSources. It is here as a discussion piece as well as a usable bit of code.&lt;br /&gt; &lt;br /&gt;The key features are a Request-scoped datacontext and entity repository classes which provide easy to use Create, Retrieve, Update and Delete (CRUD) operations implemented with Generics. It also discusses the use of DataLoadOptions and approaches to submitting changes back to the database.&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Entity Repository classes
&lt;/h2&gt;Each database entity has an associated repository class which is used to perform common CRUD operations. Specific entity controllers inherit from a generic class &lt;i&gt;GenericController&lt;/i&gt; which already implements all the basic Select, Insert, Update &amp;amp; Delete operations.&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
[System.ComponentModel.DataObject]
public class GenericController&amp;lt;TEntity, TDataContext&amp;gt; where TDataContext : DataContext
{
    public static List&amp;lt;TEntity&amp;gt; SelectAll()
    {
          ...
    }
    public static void Insert(TEntity entity)
    {
        ...
    }
    public static void Update(TEntity entity)
    {
        ...
    }
    public static void Delete(TEntity entity)
    {
        ...
    }
}
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;Specific repositories then inherit from this by specifying the entity type which they are concerned with as well as the type of the DataContext used, as follows:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
//ProductController class
public class ProductController : GenericController&amp;lt;Product, NorthwindDataContext&amp;gt;
{
}
&lt;/pre&gt; &lt;br /&gt;which allows client code such as the following:&lt;br /&gt;&lt;pre&gt;
   IList&amp;lt;Product&amp;gt; products = ProductController.SelectAll();
&lt;/pre&gt; &lt;br /&gt;The use of Generics means that I don't need to add any code at all into my ProductController to get all the standard CRUD operations in a fully type safe way. My ProductController class can now be customised to add any further data access methods which are specific to Products, for instance GetByCategoryId().&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Request scoped DataContext
&lt;/h2&gt;The second part of this solution is the request scoped DataContext. This is a pattern that is commonly used with the Hibernate OR mapper as well as elsewhere, and it means that there is only ever one DataContext per Http request which is stored in the HttpContext.Items collection. It is implemented as a protected property of the GenericController class as follows:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
        protected static TDataContext DataContext
        {
            get
            {
                //We are in a web app, use a request scope
                if (HttpContext.Current != null)
                {
                    TDataContext dataContext = (TDataContext)HttpContext.Current.Items[DataContextKey];
                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        HttpContext.Current.Items.Add(DataContextKey, dataContext);
                    }
                    return dataContext;
                }
                else
                {
 
                    // Creates a Thread Scoped DataContext object that can be reused. 
                    // The DataContext is stored in Thread local storage.
                    // See here http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=361
                    //for a discussion of this code.
 
                    LocalDataStoreSlot threadData = Thread.GetNamedDataSlot(DataContextKey);
                    object dataContext = null;
 
                    if (threadData != null)
                        dataContext = Thread.GetData(threadData);
 
                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        if(threadData == null)
                            threadData = Thread.AllocateNamedDataSlot(DataContextKey);
 
                        Thread.SetData(threadData, dataContext);
                    }
                    return (TDataContext) dataContext;
                }
 
            }
        }
&lt;/pre&gt; &lt;br /&gt;As you can see from the code above it handles being used outside a web app by storing the DataContext in a named data slot on the thread it is running in.&lt;br /&gt; &lt;br /&gt;The usefulness of this approach can be seen if you consider a page which uses a number of ObjectDataSources; if we configure our ObjectDataSource to use the DataContext directly then each one will create and dispose of a new DataContext this will not only quickly become a performance overhead, but will also present us with a problem when specifying LoadOptions for the DataContext resulting in more complex, less maintainable code or quite possibly code which doesn't specify loading options at all.&lt;br /&gt; &lt;br /&gt;It should be noted that this approach means that if I have a CategoryController class as well as a ProductController class, both of which inherit from GenericController, both of these classes will use the same DataContext. In other words the DataContext is shared across the whole request, not just by one class type.&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Custom ObjectDataSource
&lt;/h2&gt;In order for updates to work correctly with databinding it is advisable to use the GenericObjectDataSource control which is included in the DataLayer project. An ordinary ObjectDataSource control will create a new object before doing updates and if there are any unbound properties on this object, they will be left with their default values which will then be saved to the database, the GenericObjectDataSource control gets round this by retrieving the original values from the database, before updating them. For more discussions of the details behind this, see &lt;a href="https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488" class="externalLink"&gt;https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Submitting changes
&lt;/h2&gt;Another feature of the Linq to Sql architecture is the way that changes are only submitted to the database when the SubmitChanges() method is called on the DataContext. This means that we must either decide at which point to call SubmitChanges() or delegate this responsibility to client code.&lt;br /&gt;To make the classes as flexible as possible any operations which require a call to SubmitChanges (Insert, Update and Delete), are provided with a boolean parameter which specify whether to submit changes immediately or not. There is also an overload of these methods without this parameter which is equivalent to passing true (again this makes use of ObjectDatasources much more straightforward).&lt;br /&gt;The SubmitChanges method of the DataContext is also exposed through the controller class to give Client code the ability to call this explicitly.&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Sorting and Paging with GridViews
&lt;/h2&gt;There are a number of methods on the GenericController class to automatically support paging and sorting in GridViews.&lt;br /&gt;These are:&lt;br /&gt;&lt;pre&gt;
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(int maximumRows, int startRowIndex)
        {
            ...
        }
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression)
        {
         ...
        }
     
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression, int maximumRows, int startRowIndex)
        {
            ...
        }
        public static int Count()
        {
            ...
        }
&lt;/pre&gt; &lt;br /&gt;To use this functionality all you need to do is turn it on in the ObjectDataSource and GridView with the following attributes:&lt;br /&gt;ObjectDataSource: &lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
EnablePaging=&amp;quot;true&amp;quot; SelectCountMethod=&amp;quot;Count&amp;quot; SortParameterName=&amp;quot;sortExpression&amp;quot;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;Gridview:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
AllowPaging=&amp;quot;true&amp;quot; AllowSorting=&amp;quot;true&amp;quot;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;And hey presto it just works! This makes it really easy to create sortable, pagable GridViews with no extra coding.&lt;br /&gt; &lt;br /&gt;&lt;i&gt;This release also includes some code from Scott Gu's blog to support Dynamic Querying, see &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx" class="externalLink"&gt;http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; for more details&lt;/i&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Logging
&lt;/h2&gt;The code includes an easy way to configure Linq to Sql's logging feature (DataContext.Log) to write to either a text file or the System.Diagnostics.Debugger class which then appears in the output window within Visual Studio.&lt;br /&gt; &lt;br /&gt;To use this functionality you need to add the following lines into your web.config:&lt;br /&gt; &lt;br /&gt;In the &amp;lt;configSections&amp;gt; element:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
&amp;lt;section name=&amp;quot;GenericDataSection&amp;quot; type=&amp;quot;DataLayer.GenericDataSection, DataLayer&amp;quot; allowDefinition=&amp;quot;MachineToApplication&amp;quot; restartOnExternalChanges=&amp;quot;true&amp;quot; requirePermission=&amp;quot;false&amp;quot;/&amp;gt;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;Then directly after &amp;lt;configSections&amp;gt;:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
&amp;lt;GenericDataSection LogType=&amp;quot;file&amp;quot; LogFile=&amp;quot;C:\Projects\MultiTierLinqToSql_release\test.txt&amp;quot; DeleteExistingFile=&amp;quot;true&amp;quot;/&amp;gt;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;The first of these lines just declares the second line which is the one that contains the interesting stuff.&lt;br /&gt;There are 3 config options in this section:&lt;br /&gt;&lt;ol&gt;
&lt;li&gt;LogType - this can be either 'file' (logs output to a file), 'debug' (logs output to Systems.Diagnostics.Debug) or 'none' (switches logging off). &lt;/li&gt;&lt;li&gt;LogFile - only applies when LogType is set to 'file', and the default is 'log.txt' it specifies the name of the file to use for logging.&lt;/li&gt;&lt;li&gt;DeleteExistingFile - only applies when LogType is set to 'file', values can be 'true' or 'false', and the default is true. When this is set to true the file will be overwritten every time a new DataContext is created, effectively once per request. If set to false then all output is appended to the end of the file. This can result in a very large log files so be careful.&lt;/li&gt;
&lt;/ol&gt;&lt;h4&gt;
Notes
&lt;/h4&gt;As with all file logging this can be pretty detrimental to performance and so should not be left on in production.&lt;br /&gt; &lt;br /&gt;To handle the logging to the output window I have used the DebuggerWriter class described here: &lt;a href="http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11" class="externalLink"&gt;http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Error Handling
&lt;/h2&gt;Best practice for managing business rules relating to data integrity with Linq to Sql is to include these rules in partial methods in the entity classes and throw exceptions when they are violated (see http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx for more details).&lt;br /&gt;When using this strategy with an ObjectDataSource, you can then catch these exceptions in the OnUpdated or OnInserted events of your ObjectDataSource and present the information to the user. &lt;br /&gt;To do so you set the OnUpdated and/or the OnInserted attribute of your GenericObjectDatasource:&lt;br /&gt;&lt;pre&gt;
OnUpdated=&amp;quot;ProductDataSource_Updated&amp;quot;
OnInserted=&amp;quot;ProductDataSource_Updated&amp;quot;
&lt;/pre&gt; &lt;br /&gt;and then handle this event in your code behind:&lt;br /&gt;&lt;pre&gt;
protected void ProductDataSource_Updated(object sender, ObjectDataSourceStatusEventArgs e)
    {
        if (e.Exception != null)
        {
            //litError is a literal control which I want to use to display the error to the user
            litError.Text = e.Exception.Message;
            //This tells the objectDataSource that I have handled the error and not to throw it
            e.ExceptionHandled = true;
        }
    }
&lt;/pre&gt; &lt;br /&gt;There is an example of this in the Default.aspx page in the test website.&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
DataLoadOptions
&lt;/h2&gt;As has been widely noted, the way that Linq to Sql works, means that the DataLoadOptions for your DataContext need to be set &lt;i&gt;before&lt;/i&gt; any operations are carried out, and cannot subsequently be changed. This means that in my Asp.Net application I will need to set the DataLoadOptions for the whole request somewhere near the start (assuming of course that I need to set DataLoadOptions at all). It also means that my UI or business layer will need to take responsibility for this. &lt;br /&gt; &lt;br /&gt;What this means in practice is that in a classic Web forms type app I will probably set the DataLoadOptions in the OnInit event of my page, if I'm using MVC then my controller will do it. &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
The code
&lt;/h2&gt;The code consists of 4 projects; GenericDataLayer, which contains the reusable code and 3 demo/test projects&lt;br /&gt;&lt;h3&gt;
GenericDataLayer
&lt;/h3&gt;This project contains all of the code you need to use this solution, it can be compiled and referenced in your projects or run as a project within your solutions.&lt;br /&gt;It is made up of:&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;GenericController class - the main class which implements the generic CRUD methods as discussed above&lt;/li&gt;&lt;li&gt;GenericObjectDataSource - the custom ObjectDataSource to use in your aspx pages as discussed above. This control also uses the classes GenericObjectDataSourceView and ExposedSr&lt;/li&gt;&lt;li&gt;FileLogger and DebuggerWriter - classes for logging to text files and System.Debug.Out, see Logging section&lt;/li&gt;&lt;li&gt;GenericDataSection - a class to handle configuration data&lt;/li&gt;&lt;li&gt;Dynamic - some code to help in the sorting methods &lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;&lt;h3&gt;
NorthWindDataLayer
&lt;/h3&gt;This project is an example of how to use the code with your database (using Microsoft's NorthWind database), it references the GenericController project and contains all the project specific database classes that your application needs to work with. These are:&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;Linq to Sql dbml file - In this case pointing to the NorthWind database&lt;/li&gt;&lt;li&gt;Partial Entity classes which implements a custom data validation rules (see section on Error Handling) - In this project there is just one class Product which implements one rule &lt;/li&gt;&lt;li&gt;Concrete Controller classes which inherit from GenericController and implement custom data access code for specific database entities - This project has two, ProductController and CategoryController &lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;&lt;h3&gt;
A test web project
&lt;/h3&gt;This project has one page with a GridView and a FormView which use the data layer via GenericObjectDataSources to list all the products in the Northwind database, allow editing and deletion of those projects, and insert new products via the FormView. &lt;br /&gt; &lt;br /&gt;&lt;h3&gt;
A console app
&lt;/h3&gt;To test functionality outside the context of a web application &lt;br /&gt; &lt;br /&gt;To run the example project:&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;Download and unzip the release &lt;/li&gt;&lt;li&gt;Open the solution in VS2008&lt;/li&gt;&lt;li&gt;Change the connection string in the web.config to point to a Northwind database&lt;/li&gt;&lt;li&gt;Run the web project&lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;To use the code in your own projects&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;Create a class library to contain your Linq to Sql classes, partial entities and concrete repositories&lt;/li&gt;&lt;li&gt;Reference the GenericDataLayer project (either compiled or within your solution)&lt;/li&gt;&lt;li&gt;Create one entity repository class for each Linq to Sql entity, inheriting from Genericrepository&lt;/li&gt;&lt;li&gt;Optionally define any new entity specific data access operations in your entity repository classes&lt;/li&gt;&lt;li&gt;Make use of the GenericObjectDataSource to get easy inserts, updates, deletes, sorting and paging&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;</description><author>rbates</author><pubDate>Thu, 09 Apr 2009 14:29:29 GMT</pubDate><guid isPermaLink="false">Updated Wiki: Home 20090409022929P</guid></item><item><title>Updated Wiki: Home</title><link>http://www.codeplex.com/MultiTierLinqToSql/Wiki/View.aspx?title=Home&amp;version=7</link><description>&lt;div class="wikidoc"&gt;
&lt;h1&gt;
Multi tier architecture for Linq to Sql
&lt;/h1&gt;&lt;h2&gt;
Introduction
&lt;/h2&gt;This resource shows an approach for using Linq to Sql within a multi tier Asp.Net application, and particularly how it can be made to work well with ObjectDataSources. It is here as a discussion piece as well as a usable bit of code.&lt;br /&gt; &lt;br /&gt;The key features are a Request-scoped datacontext and entity controller classes which provide easy to use Create, Retrieve, Update and Delete (CRUD) operations implemented with Generics. It also discusses the use of DataLoadOptions and approaches to submitting changes back to the database.&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Entity Controller classes
&lt;/h2&gt;Each database entity has an associated controller class which is used to perform common CRUD operations. Specific entity controllers inherit from a generic class &lt;i&gt;GenericController&lt;/i&gt; which already implements all the basic Select, Insert, Update &amp;amp; Delete operations.&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
[System.ComponentModel.DataObject]
public class GenericController&amp;lt;TEntity, TDataContext&amp;gt; where TDataContext : DataContext
{
    public static List&amp;lt;TEntity&amp;gt; SelectAll()
    {
          ...
    }
    public static void Insert(TEntity entity)
    {
        ...
    }
    public static void Update(TEntity entity)
    {
        ...
    }
    public static void Delete(TEntity entity)
    {
        ...
    }
}
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;Specific controllers then inherit from this by specifying the entity type which they are concerned with as well as the type of the DataContext used, as follows:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
//ProductController class
public class ProductController : GenericController&amp;lt;Product, NorthwindDataContext&amp;gt;
{
}
&lt;/pre&gt; &lt;br /&gt;which allows client code such as the following:&lt;br /&gt;&lt;pre&gt;
   IList&amp;lt;Product&amp;gt; products = ProductController.SelectAll();
&lt;/pre&gt; &lt;br /&gt;The use of Generics means that I don't need to add any code at all into my ProductController to get all the standard CRUD operations in a fully type safe way. My ProductController class can now be customised to add any further data access methods which are specific to Products, for instance GetByCategoryId().&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Request scoped DataContext
&lt;/h2&gt;The second part of this solution is the request scoped DataContext. This is a pattern that is commonly used with the Hibernate OR mapper as well as elsewhere, and it means that there is only ever one DataContext per Http request which is stored in the HttpContext.Items collection. It is implemented as a protected property of the GenericController class as follows:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
        protected static TDataContext DataContext
        {
            get
            {
                //We are in a web app, use a request scope
                if (HttpContext.Current != null)
                {
                    TDataContext dataContext = (TDataContext)HttpContext.Current.Items[DataContextKey];
                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        HttpContext.Current.Items.Add(DataContextKey, dataContext);
                    }
                    return dataContext;
                }
                else
                {
 
                    // Creates a Thread Scoped DataContext object that can be reused. 
                    // The DataContext is stored in Thread local storage.
                    // See here http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=361
                    //for a discussion of this code.
 
                    LocalDataStoreSlot threadData = Thread.GetNamedDataSlot(DataContextKey);
                    object dataContext = null;
 
                    if (threadData != null)
                        dataContext = Thread.GetData(threadData);
 
                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        if(threadData == null)
                            threadData = Thread.AllocateNamedDataSlot(DataContextKey);
 
                        Thread.SetData(threadData, dataContext);
                    }
                    return (TDataContext) dataContext;
                }
 
            }
        }
&lt;/pre&gt; &lt;br /&gt;As you can see from the code above it handles being used outside a web app by storing the DataContext in a named data slot on the thread it is running in.&lt;br /&gt; &lt;br /&gt;The usefulness of this approach can be seen if you consider a page which uses a number of ObjectDataSources; if we configure our ObjectDataSource to use the DataContext directly then each one will create and dispose of a new DataContext this will not only quickly become a performance overhead, but will also present us with a problem when specifying LoadOptions for the DataContext resulting in more complex, less maintainable code or quite possibly code which doesn't specify loading options at all.&lt;br /&gt; &lt;br /&gt;It should be noted that this approach means that if I have a CategoryController class as well as a ProductController class, both of which inherit from GenericController, both of these classes will use the same DataContext. In other words the DataContext is shared across the whole request, not just by one class type.&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Custom ObjectDataSource
&lt;/h2&gt;In order for updates to work correctly with databinding it is advisable to use the GenericObjectDataSource control which is included in the DataLayer project. An ordinary ObjectDataSource control will create a new object before doing updates and if there are any unbound properties on this object, they will be left with their default values which will then be saved to the database, the GenericObjectDataSource control gets round this by retrieving the original values from the database, before updating them. For more discussions of the details behind this, see &lt;a href="https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488" class="externalLink"&gt;https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Submitting changes
&lt;/h2&gt;Another feature of the Linq to Sql architecture is the way that changes are only submitted to the database when the SubmitChanges() method is called on the DataContext. This means that we must either decide at which point to call SubmitChanges() or delegate this responsibility to client code.&lt;br /&gt;To make the classes as flexible as possible any operations which require a call to SubmitChanges (Insert, Update and Delete), are provided with a boolean parameter which specify whether to submit changes immediately or not. There is also an overload of these methods without this parameter which is equivalent to passing true (again this makes use of ObjectDatasources much more straightforward).&lt;br /&gt;The SubmitChanges method of the DataContext is also exposed through the controller class to give Client code the ability to call this explicitly.&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Sorting and Paging with GridViews
&lt;/h2&gt;There are a number of methods on the GenericController class to automatically support paging and sorting in GridViews.&lt;br /&gt;These are:&lt;br /&gt;&lt;pre&gt;
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(int maximumRows, int startRowIndex)
        {
            ...
        }
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression)
        {
         ...
        }
     
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression, int maximumRows, int startRowIndex)
        {
            ...
        }
        public static int Count()
        {
            ...
        }
&lt;/pre&gt; &lt;br /&gt;To use this functionality all you need to do is turn it on in the ObjectDataSource and GridView with the following attributes:&lt;br /&gt;ObjectDataSource: &lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
EnablePaging=&amp;quot;true&amp;quot; SelectCountMethod=&amp;quot;Count&amp;quot; SortParameterName=&amp;quot;sortExpression&amp;quot;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;Gridview:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
AllowPaging=&amp;quot;true&amp;quot; AllowSorting=&amp;quot;true&amp;quot;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;And hey presto it just works! This makes it really easy to create sortable, pagable GridViews with no extra coding.&lt;br /&gt; &lt;br /&gt;&lt;i&gt;This release also includes some code from Scott Gu's blog to support Dynamic Querying, see &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx" class="externalLink"&gt;http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; for more details&lt;/i&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Logging
&lt;/h2&gt;The code includes an easy way to configure Linq to Sql's logging feature (DataContext.Log) to write to either a text file or the System.Diagnostics.Debugger class which then appears in the output window within Visual Studio.&lt;br /&gt; &lt;br /&gt;To use this functionality you need to add the following lines into your web.config:&lt;br /&gt; &lt;br /&gt;In the &amp;lt;configSections&amp;gt; element:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
&amp;lt;section name=&amp;quot;GenericDataSection&amp;quot; type=&amp;quot;DataLayer.GenericDataSection, DataLayer&amp;quot; allowDefinition=&amp;quot;MachineToApplication&amp;quot; restartOnExternalChanges=&amp;quot;true&amp;quot; requirePermission=&amp;quot;false&amp;quot;/&amp;gt;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;Then directly after &amp;lt;configSections&amp;gt;:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
&amp;lt;GenericDataSection LogType=&amp;quot;file&amp;quot; LogFile=&amp;quot;C:\Projects\MultiTierLinqToSql_release\test.txt&amp;quot; DeleteExistingFile=&amp;quot;true&amp;quot;/&amp;gt;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;The first of these lines just declares the second line which is the one that contains the interesting stuff.&lt;br /&gt;There are 3 config options in this section:&lt;br /&gt;&lt;ol&gt;
&lt;li&gt;LogType - this can be either 'file' (logs output to a file), 'debug' (logs output to Systems.Diagnostics.Debug) or 'none' (switches logging off). &lt;/li&gt;&lt;li&gt;LogFile - only applies when LogType is set to 'file', and the default is 'log.txt' it specifies the name of the file to use for logging.&lt;/li&gt;&lt;li&gt;DeleteExistingFile - only applies when LogType is set to 'file', values can be 'true' or 'false', and the default is true. When this is set to true the file will be overwritten every time a new DataContext is created, effectively once per request. If set to false then all output is appended to the end of the file. This can result in a very large log files so be careful.&lt;/li&gt;
&lt;/ol&gt;&lt;h4&gt;
Notes
&lt;/h4&gt;As with all file logging this can be pretty detrimental to performance and so should not be left on in production.&lt;br /&gt; &lt;br /&gt;To handle the logging to the output window I have used the DebuggerWriter class described here: &lt;a href="http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11" class="externalLink"&gt;http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Error Handling
&lt;/h2&gt;Best practice for managing business rules relating to data integrity with Linq to Sql is to include these rules in partial methods in the entity classes and throw exceptions when they are violated (see http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx for more details).&lt;br /&gt;When using this strategy with an ObjectDataSource, you can then catch these exceptions in the OnUpdated or OnInserted events of your ObjectDataSource and present the information to the user. &lt;br /&gt;To do so you set the OnUpdated and/or the OnInserted attribute of your GenericObjectDatasource:&lt;br /&gt;&lt;pre&gt;
OnUpdated=&amp;quot;ProductDataSource_Updated&amp;quot;
OnInserted=&amp;quot;ProductDataSource_Updated&amp;quot;
&lt;/pre&gt; &lt;br /&gt;and then handle this event in your code behind:&lt;br /&gt;&lt;pre&gt;
protected void ProductDataSource_Updated(object sender, ObjectDataSourceStatusEventArgs e)
    {
        if (e.Exception != null)
        {
            //litError is a literal control which I want to use to display the error to the user
            litError.Text = e.Exception.Message;
            //This tells the objectDataSource that I have handled the error and not to throw it
            e.ExceptionHandled = true;
        }
    }
&lt;/pre&gt; &lt;br /&gt;There is an example of this in the Default.aspx page in the test website.&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
DataLoadOptions
&lt;/h2&gt;As has been widely noted, the way that Linq to Sql works, means that the DataLoadOptions for your DataContext need to be set &lt;i&gt;before&lt;/i&gt; any operations are carried out, and cannot subsequently be changed. This means that in my Asp.Net application I will need to set the DataLoadOptions for the whole request somewhere near the start (assuming of course that I need to set DataLoadOptions at all). It also means that my UI or business layer will need to take responsibility for this. &lt;br /&gt; &lt;br /&gt;What this means in practice is that in a classic Web forms type app I will probably set the DataLoadOptions in the OnInit event of my page, if I'm using MVC then my controller will do it. &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
The code
&lt;/h2&gt;The code consists of 4 projects; GenericDataLayer, which contains the reusable code and 3 demo/test projects&lt;br /&gt;&lt;h3&gt;
GenericDataLayer
&lt;/h3&gt;This project contains all of the code you need to use this solution, it can be compiled and referenced in your projects or run as a project within your solutions.&lt;br /&gt;It is made up of:&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;GenericController class - the main class which implements the generic CRUD methods as discussed above&lt;/li&gt;&lt;li&gt;GenericObjectDataSource - the custom ObjectDataSource to use in your aspx pages as discussed above. This control also uses the classes GenericObjectDataSourceView and ExposedSr&lt;/li&gt;&lt;li&gt;FileLogger and DebuggerWriter - classes for logging to text files and System.Debug.Out, see Logging section&lt;/li&gt;&lt;li&gt;GenericDataSection - a class to handle configuration data&lt;/li&gt;&lt;li&gt;Dynamic - some code to help in the sorting methods &lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;&lt;h3&gt;
NorthWindDataLayer
&lt;/h3&gt;This project is an example of how to use the code with your database (using Microsoft's NorthWind database), it references the GenericController project and contains all the project specific database classes that your application needs to work with. These are:&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;Linq to Sql dbml file - In this case pointing to the NorthWind database&lt;/li&gt;&lt;li&gt;Partial Entity classes which implements a custom data validation rules (see section on Error Handling) - In this project there is just one class Product which implements one rule &lt;/li&gt;&lt;li&gt;Concrete Controller classes which inherit from GenericController and implement custom data access code for specific database entities - This project has two, ProductController and CategoryController &lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;&lt;h3&gt;
A test web project
&lt;/h3&gt;This project has one page with a GridView and a FormView which use the data layer via GenericObjectDataSources to list all the products in the Northwind database, allow editing and deletion of those projects, and insert new products via the FormView. &lt;br /&gt; &lt;br /&gt;&lt;h3&gt;
A console app
&lt;/h3&gt;To test functionality outside the context of a web application &lt;br /&gt; &lt;br /&gt;To run the example project:&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;Download and unzip the release &lt;/li&gt;&lt;li&gt;Open the solution in VS2008&lt;/li&gt;&lt;li&gt;Change the connection string in the web.config to point to a Northwind database&lt;/li&gt;&lt;li&gt;Run the web project&lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;To use the code in your own projects&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;Create a class library to contain your Linq to Sql classes, partial entities and concrete controllers&lt;/li&gt;&lt;li&gt;Reference the GenericDataLayer project (either compiled or within your solution)&lt;/li&gt;&lt;li&gt;Create one entity controller class for each Linq to Sql entity, inheriting from GenericController&lt;/li&gt;&lt;li&gt;Optionally define any new entity specific data access operations in your entity controller classes&lt;/li&gt;&lt;li&gt;Make use of the GenericObjectDataSource to get easy inserts, updates, deletes, sorting and paging&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;</description><author>rbates</author><pubDate>Thu, 30 Oct 2008 16:38:54 GMT</pubDate><guid isPermaLink="false">Updated Wiki: Home 20081030043854P</guid></item><item><title>Updated Wiki: Home</title><link>http://www.codeplex.com/MultiTierLinqToSql/Wiki/View.aspx?title=Home&amp;version=6</link><description>&lt;div class="wikidoc"&gt;
&lt;h1&gt;
Multi tier architecture for Linq to Sql
&lt;/h1&gt;&lt;h2&gt;
Introduction
&lt;/h2&gt;This resource shows an approach for using Linq to Sql within a multi tier Asp.Net application, and particularly how it can be made to work well with ObjectDataSources. It is here as a discussion piece as well as a usable bit of code.&lt;br /&gt; &lt;br /&gt;The key features are a Request-scoped datacontext and entity controller classes which provide easy to use Create, Retrieve, Update and Delete (CRUD) operations implemented with Generics. It also discusses the use of DataLoadOptions and approaches to submitting changes back to the database.&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Entity Controller classes
&lt;/h2&gt;Each database entity has an associated controller class which is used to perform common CRUD operations. Specific entity controllers inherit from a generic class &lt;i&gt;GenericController&lt;/i&gt; which already implements all the basic Select, Insert, Update &amp;amp; Delete operations.&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
[System.ComponentModel.DataObject]
public class GenericController&amp;lt;TEntity, TDataContext&amp;gt; where TDataContext : DataContext
{
    public static List&amp;lt;TEntity&amp;gt; SelectAll()
    {
          ...
    }
    public static void Insert(TEntity entity)
    {
        ...
    }
    public static void Update(TEntity entity)
    {
        ...
    }
    public static void Delete(TEntity entity)
    {
        ...
    }
}
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;Specific controllers then inherit from this by specifying the entity type which they are concerned with as well as the type of the DataContext used, as follows:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
//ProductController class
public class ProductController : GenericController&amp;lt;Product, NorthwindDataContext&amp;gt;
{
}
&lt;/pre&gt; &lt;br /&gt;which allows client code such as the following:&lt;br /&gt;&lt;pre&gt;
   IList&amp;lt;Product&amp;gt; products = ProductController.SelectAll();
&lt;/pre&gt; &lt;br /&gt;The use of Generics means that I don't need to add any code at all into my ProductController to get all the standard CRUD operations in a fully type safe way. My ProductController class can now be customised to add any further data access methods which are specific to Products, for instance GetByCategoryId().&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Request scoped DataContext
&lt;/h2&gt;The second part of this solution is the request scoped DataContext. This is a pattern that is commonly used with the Hibernate OR mapper as well as elsewhere, and it means that there is only ever one DataContext per Http request which is stored in the HttpContext.Items collection. It is implemented as a protected property of the GenericController class as follows:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
        protected static TDataContext DataContext
        {
            get
            {
                //We are in a web app, use a request scope
                if (HttpContext.Current != null)
                {
                    TDataContext dataContext = (TDataContext)HttpContext.Current.Items[DataContextKey];
                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        HttpContext.Current.Items.Add(DataContextKey, dataContext);
                    }
                    return dataContext;
                }
                else
                {
 
                    // Creates a Thread Scoped DataContext object that can be reused. 
                    // The DataContext is stored in Thread local storage.
                    // See here http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=361
                    //for a discussion of this code.
 
                    LocalDataStoreSlot threadData = Thread.GetNamedDataSlot(DataContextKey);
                    object dataContext = null;
 
                    if (threadData != null)
                        dataContext = Thread.GetData(threadData);
 
                    if (dataContext == null)
                    {
                        dataContext = CreateDataContext();
                        if(threadData == null)
                            threadData = Thread.AllocateNamedDataSlot(DataContextKey);
 
                        Thread.SetData(threadData, dataContext);
                    }
                    return (TDataContext) dataContext;
                }
 
            }
        }
&lt;/pre&gt; &lt;br /&gt;As you can see from the code above it handles being used outside a web app by storing the DataContext in a named data slot on the thread it is running in.&lt;br /&gt; &lt;br /&gt;The usefulness of this approach can be seen if you consider a page which uses a number of ObjectDataSources; if we configure our ObjectDataSource to use the DataContext directly then each one will create and dispose of a new DataContext this will not only quickly become a performance overhead, but will also present us with a problem when specifying LoadOptions for the DataContext resulting in more complex, less maintainable code or quite possibly code which doesn't specify loading options at all.&lt;br /&gt; &lt;br /&gt;It should be noted that this approach means that if I have a CategoryController class as well as a ProductController class, both of which inherit from GenericController, both of these classes will use the same DataContext. In other words the DataContext is shared across the whole request, not just by one class type.&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Custom ObjectDataSource
&lt;/h2&gt;In order for updates to work correctly with databinding it is advisable to use the GenericObjectDataSource control which is included in the DataLayer project. An ordinary ObjectDataSource control will create a new object before doing updates and if there are any unbound properties on this object, they will be left with their default values which will then be saved to the database, the GenericObjectDataSource control gets round this by retrieving the original values from the database, before updating them. For more discussions of the details behind this, see &lt;a href="https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488" class="externalLink"&gt;https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=multitierlinqtosql&amp;amp;ThreadId=488&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Submitting changes
&lt;/h2&gt;Another feature of the Linq to Sql architecture is the way that changes are only submitted to the database when the SubmitChanges() method is called on the DataContext. This means that we must either decide at which point to call SubmitChanges() or delegate this responsibility to client code.&lt;br /&gt;To make the classes as flexible as possible any operations which require a call to SubmitChanges (Insert, Update and Delete), are provided with a boolean parameter which specify whether to submit changes immediately or not. There is also an overload of these methods without this parameter which is equivalent to passing true (again this makes use of ObjectDatasources much more straightforward).&lt;br /&gt;The SubmitChanges method of the DataContext is also exposed through the controller class to give Client code the ability to call this explicitly.&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Sorting and Paging with GridViews
&lt;/h2&gt;There are a number of methods on the GenericController class to automatically support paging and sorting in GridViews.&lt;br /&gt;These are:&lt;br /&gt;&lt;pre&gt;
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(int maximumRows, int startRowIndex)
        {
            ...
        }
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression)
        {
         ...
        }
     
        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression, int maximumRows, int startRowIndex)
        {
            ...
        }
        public static int Count()
        {
            ...
        }
&lt;/pre&gt; &lt;br /&gt;To use this functionality all you need to do is turn it on in the ObjectDataSource and GridView with the following attributes:&lt;br /&gt;ObjectDataSource: &lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
EnablePaging=&amp;quot;true&amp;quot; SelectCountMethod=&amp;quot;Count&amp;quot; SortParameterName=&amp;quot;sortExpression&amp;quot;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;Gridview:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
AllowPaging=&amp;quot;true&amp;quot; AllowSorting=&amp;quot;true&amp;quot;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;And hey presto it just works! This makes it really easy to create sortable, pagable GridViews with no extra coding.&lt;br /&gt; &lt;br /&gt;&lt;i&gt;This release also includes some code from Scott Gu's blog to support Dynamic Querying, see &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx" class="externalLink"&gt;http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; for more details&lt;/i&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Logging
&lt;/h2&gt;The code includes an easy way to configure Linq to Sql's logging feature (DataContext.Log) to write to either a text file or the System.Diagnostics.Debugger class which then appears in the output window within Visual Studio.&lt;br /&gt; &lt;br /&gt;To use this functionality you need to add the following lines into your web.config:&lt;br /&gt; &lt;br /&gt;In the &amp;lt;configSections&amp;gt; element:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
&amp;lt;section name=&amp;quot;GenericDataSection&amp;quot; type=&amp;quot;DataLayer.GenericDataSection, DataLayer&amp;quot; allowDefinition=&amp;quot;MachineToApplication&amp;quot; restartOnExternalChanges=&amp;quot;true&amp;quot; requirePermission=&amp;quot;false&amp;quot;/&amp;gt;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;Then directly after &amp;lt;configSections&amp;gt;:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
&amp;lt;GenericDataSection LogType=&amp;quot;file&amp;quot; LogFile=&amp;quot;C:\Projects\MultiTierLinqToSql_release\test.txt&amp;quot; DeleteExistingFile=&amp;quot;true&amp;quot;/&amp;gt;
&lt;/pre&gt; &lt;br /&gt; &lt;br /&gt;The first of these lines just declares the second line which is the one that contains the interesting stuff.&lt;br /&gt;There are 3 config options in this section:&lt;br /&gt;&lt;ol&gt;
&lt;li&gt;LogType - this can be either 'file' (logs output to a file), 'debug' (logs output to Systems.Diagnostics.Debug) or 'none' (switches logging off). &lt;/li&gt;&lt;li&gt;LogFile - only applies when LogType is set to 'file', and the default is 'log.txt' it specifies the name of the file to use for logging.&lt;/li&gt;&lt;li&gt;DeleteExistingFile - only applies when LogType is set to 'file', values can be 'true' or 'false', and the default is true. When this is set to true the file will be overwritten every time a new DataContext is created, effectively once per request. If set to false then all output is appended to the end of the file. This can result in a very large log files so be careful.&lt;/li&gt;
&lt;/ol&gt;&lt;h4&gt;
Notes
&lt;/h4&gt;As with all file logging this can be pretty detrimental to performance and so should not be left on in production.&lt;br /&gt; &lt;br /&gt;To handle the logging to the output window I have used the DebuggerWriter class described here: &lt;a href="http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11" class="externalLink"&gt;http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Error Handling
&lt;/h2&gt;Best practice for managing business rules relating to data integrity with Linq to Sql is to include these rules in partial methods in the entity classes and throw exceptions when they are violated (see http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx for more details).&lt;br /&gt;When using this strategy with an ObjectDataSource, you can then catch these exceptions in the OnUpdated or OnInserted events of your ObjectDataSource and present the information to the user. &lt;br /&gt;To do so you set the OnUpdated and/or the OnInserted attribute of your GenericObjectDatasource:&lt;br /&gt;&lt;pre&gt;
OnUpdated=&amp;quot;ProductDataSource_Updated&amp;quot;
OnInserted=&amp;quot;ProductDataSource_Updated&amp;quot;
&lt;/pre&gt; &lt;br /&gt;and then handle this event in your code behind:&lt;br /&gt;&lt;pre&gt;
protected void ProductDataSource_Updated(object sender, ObjectDataSourceStatusEventArgs e)
    {
        if (e.Exception != null)
        {
            //litError is a literal control which I want to use to display the error to the user
            litError.Text = e.Exception.Message;
            //This tells the objectDataSource that I have handled the error and not to throw it
            e.ExceptionHandled = true;
        }
    }
&lt;/pre&gt; &lt;br /&gt;There is an example of this in the Default.aspx page in the test website.&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
DataLoadOptions
&lt;/h2&gt;As has been widely noted, the way that Linq to Sql works, means that the DataLoadOptions for your DataContext need to be set &lt;i&gt;before&lt;/i&gt; any operations are carried out, and cannot subsequently be changed. This means that in my Asp.Net application I will need to set the DataLoadOptions for the whole request somewhere near the start (assuming of course that I need to set DataLoadOptions at all). It also means that my UI or business layer will need to take responsibility for this. &lt;br /&gt; &lt;br /&gt;What this means in practice is that in a classic Web forms type app I will probably set the DataLoadOptions in the OnInit event of my page, if I'm using MVC then my controller will do it. &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
The code
&lt;/h2&gt;The code consists of 3 projects&lt;br /&gt;&lt;h3&gt;
The data access layer
&lt;/h3&gt;This is made up of:&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;Linq to Sql dataclasses generated from the Northwind database and a Product class which implements a custom validation rule (see section on Error Handling)&lt;/li&gt;&lt;li&gt;GenericController class - the main core of the project as discussed above and two concrete subclasses ProductController and CategoryController.&lt;/li&gt;&lt;li&gt;GenericObjectDataSource - the custom control discussed above, also uses the classes GenericObjectDataSourceView and ExposedSr&lt;/li&gt;&lt;li&gt;FileLogger and DebuggerWriter - classes for logging to text files and System.Debug.Out&lt;/li&gt;&lt;li&gt;GenericDataSection - a class to handle configuration data&lt;/li&gt;&lt;li&gt;Dynamic - some code to help in the sorting methods &lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;&lt;h3&gt;
A test web project
&lt;/h3&gt;This project has one page with a GridView and a FormView which use the data layer via ObjectDataSources to list all the products in the Northwind database, allow editing and deletion of those projects, and insert new products via the FormView. &lt;br /&gt; &lt;br /&gt;&lt;h3&gt;
A console app
&lt;/h3&gt;To test functionality outside the context of a web application &lt;br /&gt; &lt;br /&gt;To run the example project:&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;Download and unzip the release &lt;/li&gt;&lt;li&gt;Open the solution in VS2008&lt;/li&gt;&lt;li&gt;Change the connection string in the web.config to point to a Northwind database&lt;/li&gt;&lt;li&gt;Run the web project&lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;To use the code in your own projects&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;Copy the class GenericController into your Linq to Sql project&lt;/li&gt;&lt;li&gt;Create one entity controller class for each Linq to Sql entity, inheriting from GenericController&lt;/li&gt;&lt;li&gt;Optionally define any new entity specific data access operations in your entity controller classes&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;</description><author>rbates</author><pubDate>Thu, 30 Oct 2008 16:14:43 GMT</pubDate><guid isPermaLink="false">Updated Wiki: Home 20081030041443P</guid></item></channel></rss>