<?xml version="1.0"?><?xml-stylesheet type="text/xsl" href="http://code.msdn.microsoft.com/rss.xsl"?><rss version="2.0"><channel><title>An Example of a Multi Tier Architecture for Linq to Sql</title><link>http://code.msdn.microsoft.com/multitierlinqtosql/Project/ProjectRss.aspx</link><description>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 pi...</description><item><title>NEW POST: What is the fastest way to get a scalar value back</title><link>http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=976</link><description>&lt;div class="wikidoc"&gt;
What is the fastest way to get a scalar value&lt;br /&gt; &lt;br /&gt;I am wondering about the most efficient way to get back 1 non key value from an entity. &lt;br /&gt; &lt;br /&gt;Things I would consider are &lt;br /&gt;1.	pre compiled queries &lt;br /&gt;2.	Object Tracking&lt;br /&gt;3.	Creating a “new” entity.&lt;br /&gt; &lt;br /&gt;See this interesting article from Sidar&lt;br /&gt; &lt;br /&gt;http://www.sidarok.com/web/blog/content/2008/05/02/10-tips-to-improve-your-linq-to-sql-application-performance.html&lt;br /&gt;
&lt;/div&gt;</description><author>tintin5</author><pubDate>Wed, 19 Nov 2008 16:27:19 GMT</pubDate><guid isPermaLink="false">NEW POST: What is the fastest way to get a scalar value back 20081119P</guid></item><item><title>NEW POST: How to use in NON ASP.NET code sections?</title><link>http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=361</link><description>&lt;div class="wikidoc"&gt;
Hello all, this project has now moved to http://www.codeplex.com/MultiTierLinqToSql&lt;br /&gt;The most recent version also has the method to discard the datacontext requested in this thread&lt;br /&gt;
&lt;/div&gt;</description><author>rbates</author><pubDate>Wed, 05 Nov 2008 11:18:33 GMT</pubDate><guid isPermaLink="false">NEW POST: How to use in NON ASP.NET code sections? 20081105A</guid></item><item><title>NEW POST: Problem on Update</title><link>http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=379</link><description>&lt;div class="wikidoc"&gt;
Hello rabindradalai, I can't reproduce this error but I think it is because the movId column is the primary key of the table. You might be better fetching the entity first with GetEntity(id) and then updating it. &lt;br /&gt;If you have any other questions then post them on the CodePlex site:&lt;br /&gt;http://www.codeplex.com/MultiTierLinqToSql&lt;br /&gt;
&lt;/div&gt;</description><author>rbates</author><pubDate>Wed, 05 Nov 2008 11:15:26 GMT</pubDate><guid isPermaLink="false">NEW POST: Problem on Update 20081105A</guid></item><item><title>NEW POST: Problem on Update</title><link>http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=379</link><description>&lt;div class="wikidoc"&gt;
 &lt;br /&gt;&lt;div class="quote"&gt;
 &lt;br /&gt;RTPeat wrote:&lt;br /&gt;Found the bug, problem solved.&lt;br /&gt; &lt;br /&gt;
&lt;/div&gt; &lt;br /&gt;Hi RTPeat, what was the problem you are facing..and how did you solved it. is it similar to the one that i am facing below:&lt;br /&gt; &lt;br /&gt;Hi,&lt;br /&gt; &lt;br /&gt;I have cerated my own DBMovieController&amp;lt;TEntity&amp;gt; which is inherited from GenericController&amp;lt;TEntity, DBMovieDataContext&amp;gt; where TEntity : class&lt;br /&gt; &lt;br /&gt;when i try to call the following code &lt;br /&gt; &lt;br /&gt;tblMain manupdate = new tblMain();&lt;br /&gt;manupdate.movID = &amp;quot;3&amp;quot;;&lt;br /&gt;manupdate.movTitle = &amp;quot;FANNA !&amp;quot;;&lt;br /&gt;manupdate.movRunTime = 30;&lt;br /&gt;DBMovieController&amp;lt;tblMain&amp;gt;.Update(manupdate);&lt;br /&gt; &lt;br /&gt;it throws following error, but my movID is not a identity column in tblMain.&lt;br /&gt; &lt;br /&gt;Value of member 'movID' of an object of type 'tblMain' changed.&lt;br /&gt;A member defining the identity of the object cannot be changed.&lt;br /&gt;Consider adding a new object with new identity and deleting the existing one instead&lt;br /&gt; &lt;br /&gt;please give some inputs..&lt;br /&gt;
&lt;/div&gt;</description><author>rabindradalai</author><pubDate>Mon, 03 Nov 2008 08:12:19 GMT</pubDate><guid isPermaLink="false">NEW POST: Problem on Update 20081103A</guid></item><item><title>NEW POST: Problem on Update</title><link>http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=379</link><description>&lt;div class="wikidoc"&gt;
Hi,&lt;br /&gt; &lt;br /&gt;I have cerated my own DBMovieController&amp;lt;TEntity&amp;gt; which is inherited from  GenericController&amp;lt;TEntity, DBMovieDataContext&amp;gt; where TEntity : class&lt;br /&gt; &lt;br /&gt;when i try to call the following code &lt;br /&gt; &lt;br /&gt; tblMain manupdate = new tblMain();&lt;br /&gt;        manupdate.movID = &amp;quot;3&amp;quot;;&lt;br /&gt;        manupdate.movTitle = &amp;quot;FANNA !&amp;quot;;&lt;br /&gt;        manupdate.movRunTime = 30;&lt;br /&gt;        DBMovieController&amp;lt;tblMain&amp;gt;.Update(manupdate);&lt;br /&gt; &lt;br /&gt;it throws following error, but my movID is not a identity column in tblMain.&lt;br /&gt; &lt;br /&gt;Value of member 'movID' of an object of type 'tblMain' changed.&lt;br /&gt;A member defining the identity of the object cannot be changed.&lt;br /&gt;Consider adding a new object with new identity and deleting the existing one instead&lt;br /&gt; &lt;br /&gt;please give some inputs..&lt;br /&gt;
&lt;/div&gt;</description><author>rabindradalai</author><pubDate>Mon, 03 Nov 2008 08:01:22 GMT</pubDate><guid isPermaLink="false">NEW POST: Problem on Update 20081103A</guid></item><item><title>UPDATED WIKI: Home</title><link>http://code.msdn.microsoft.com/multitierlinqtosql/Wiki/View.aspx?title=Home&amp;version=38</link><description>&lt;div class="wikidoc"&gt;
&lt;h1&gt;
This project is now being hosted on CodePlex
&lt;/h1&gt;&lt;a href="http://www.codeplex.com/MultiTierLinqToSql" class="externalLink"&gt;http://www.codeplex.com/MultiTierLinqToSql&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;Please post any questions etc. over there as this site will no longer be updated&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&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;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;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;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[&amp;quot;_dataContext&amp;quot;];
                    if (_dataContext == null)
                    {
                        _dataContext = Activator.CreateInstance&amp;lt;TDataContext&amp;gt;();
                        HttpContext.Current.Items.Add(&amp;quot;_dataContext&amp;quot;, _dataContext);
                    }
                    return _dataContext;
                }
                else
                {
                    //If this is not a web app then just create a datacontext
                    //which will have the same lifespan as the app itself
                    //This is only really to support unit tests and should not
                    //be used in any production code. A better way to use this
                    //code with unit tests is to mock the HttpContext
                    if (_dataContext == null)
                    {
                        _dataContext = Activator.CreateInstance&amp;lt;TDataContext&amp;gt;();
                    }
                    return _dataContext;
                }
            }
        }
&lt;/pre&gt;Using the HttpContext.Items collection does introduce a dependency on System.Web to your data layer, but I've made the decision that since this solution is specifically designed for use in Asp.Net applications, this is acceptable. Checking for a valid HttpContext and then using an static variable if it doesn't exist gives a bit of flexibility to use the class outside of a web app, for instance in unit tests, although this will produce subtly different results, so mocking the HttpContext would probably be a better approach.&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 necessary to use the GenericObjectDataSource control which is included in the DataLayer project. 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;
DataLoadOptions
&lt;/h2&gt;Before going any further, we need to look at the issue of DataLoadOptions. As a number of people have 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. I don't really have a problem with this, particularly in the case of an MVC app as I think this is probably the best place to actually specify how you want your data loading logic to work. I'm interested to hear other opinions on this.&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;
New stuff added in Release 1.2
&lt;/h2&gt;There are now a number of new methods added to the GenericController class to automatically support paging and sorting in GridViews.&lt;br /&gt;These are:&lt;br /&gt; &lt;br /&gt;public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(int maximumRows, int startRowIndex)&lt;br /&gt;        {&lt;br /&gt;            ...&lt;br /&gt;        }&lt;br /&gt;        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression)&lt;br /&gt;        {&lt;br /&gt;         ...&lt;br /&gt;        }&lt;br /&gt;     &lt;br /&gt;        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression, int maximumRows, int startRowIndex)&lt;br /&gt;        {&lt;br /&gt;            ...&lt;br /&gt;        }&lt;br /&gt;        public static int Count()&lt;br /&gt;        {&lt;br /&gt;            ...&lt;br /&gt;        }&lt;br /&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;EnablePaging=&amp;quot;true&amp;quot; SelectCountMethod=&amp;quot;Count&amp;quot; SortParameterName=&amp;quot;sortExpression&amp;quot;&lt;br /&gt; &lt;br /&gt;Gridview:&lt;br /&gt;AllowPaging=&amp;quot;true&amp;quot; AllowSorting=&amp;quot;true&amp;quot;&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;
New stuff in release 1.6
&lt;/h2&gt;&lt;h4&gt;
Logging
&lt;/h4&gt;There is now 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;&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;br /&gt; &lt;br /&gt;Then directly after &amp;lt;configSections&amp;gt;:&lt;br /&gt; &lt;br /&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;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;br /&gt;&lt;h4&gt;
Notes
&lt;/h4&gt;As with all file logging this can be pretty detrimental to performance and so should only be used when debugging.&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;
The code
&lt;/h2&gt;The code consists of 2 projects&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;The data access layer - this is made up of Linq to Sql dataclasses generated from the Northwind database, a class &lt;b&gt;GenericController&lt;/b&gt; (discussed above) and two concrete subclasses ProductController and CategoryController.&lt;/li&gt;&lt;li&gt;A test web project - 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;/li&gt;
&lt;/ul&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 17:56:17 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: Home 20081030P</guid></item><item><title>UPDATED WIKI: Home</title><link>http://code.msdn.microsoft.com/multitierlinqtosql/Wiki/View.aspx?title=Home&amp;version=37</link><description>&lt;div class="wikidoc"&gt;
&lt;h1&gt;
This project is now being hosted on CodePlex
&lt;/h1&gt;http://www.codeplex.com/MultiTierLinqToSql&lt;br /&gt; &lt;br /&gt;Please post any questions etc. over there as this site will no longer be updated&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&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;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;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;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[&amp;quot;_dataContext&amp;quot;];
                    if (_dataContext == null)
                    {
                        _dataContext = Activator.CreateInstance&amp;lt;TDataContext&amp;gt;();
                        HttpContext.Current.Items.Add(&amp;quot;_dataContext&amp;quot;, _dataContext);
                    }
                    return _dataContext;
                }
                else
                {
                    //If this is not a web app then just create a datacontext
                    //which will have the same lifespan as the app itself
                    //This is only really to support unit tests and should not
                    //be used in any production code. A better way to use this
                    //code with unit tests is to mock the HttpContext
                    if (_dataContext == null)
                    {
                        _dataContext = Activator.CreateInstance&amp;lt;TDataContext&amp;gt;();
                    }
                    return _dataContext;
                }
            }
        }
&lt;/pre&gt;Using the HttpContext.Items collection does introduce a dependency on System.Web to your data layer, but I've made the decision that since this solution is specifically designed for use in Asp.Net applications, this is acceptable. Checking for a valid HttpContext and then using an static variable if it doesn't exist gives a bit of flexibility to use the class outside of a web app, for instance in unit tests, although this will produce subtly different results, so mocking the HttpContext would probably be a better approach.&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 necessary to use the GenericObjectDataSource control which is included in the DataLayer project. 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;
DataLoadOptions
&lt;/h2&gt;Before going any further, we need to look at the issue of DataLoadOptions. As a number of people have 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. I don't really have a problem with this, particularly in the case of an MVC app as I think this is probably the best place to actually specify how you want your data loading logic to work. I'm interested to hear other opinions on this.&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;
New stuff added in Release 1.2
&lt;/h2&gt;There are now a number of new methods added to the GenericController class to automatically support paging and sorting in GridViews.&lt;br /&gt;These are:&lt;br /&gt; &lt;br /&gt;public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(int maximumRows, int startRowIndex)&lt;br /&gt;        {&lt;br /&gt;            ...&lt;br /&gt;        }&lt;br /&gt;        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression)&lt;br /&gt;        {&lt;br /&gt;         ...&lt;br /&gt;        }&lt;br /&gt;     &lt;br /&gt;        public static IQueryable&amp;lt;TEntity&amp;gt; SelectAll(string sortExpression, int maximumRows, int startRowIndex)&lt;br /&gt;        {&lt;br /&gt;            ...&lt;br /&gt;        }&lt;br /&gt;        public static int Count()&lt;br /&gt;        {&lt;br /&gt;            ...&lt;br /&gt;        }&lt;br /&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;EnablePaging=&amp;quot;true&amp;quot; SelectCountMethod=&amp;quot;Count&amp;quot; SortParameterName=&amp;quot;sortExpression&amp;quot;&lt;br /&gt; &lt;br /&gt;Gridview:&lt;br /&gt;AllowPaging=&amp;quot;true&amp;quot; AllowSorting=&amp;quot;true&amp;quot;&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;
New stuff in release 1.6
&lt;/h2&gt;&lt;h4&gt;
Logging
&lt;/h4&gt;There is now 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;&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;br /&gt; &lt;br /&gt;Then directly after &amp;lt;configSections&amp;gt;:&lt;br /&gt; &lt;br /&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;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;br /&gt;&lt;h4&gt;
Notes
&lt;/h4&gt;As with all file logging this can be pretty detrimental to performance and so should only be used when debugging.&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;
The code
&lt;/h2&gt;The code consists of 2 projects&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;The data access layer - this is made up of Linq to Sql dataclasses generated from the Northwind database, a class &lt;b&gt;GenericController&lt;/b&gt; (discussed above) and two concrete subclasses ProductController and CategoryController.&lt;/li&gt;&lt;li&gt;A test web project - 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;/li&gt;
&lt;/ul&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 17:55:59 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: Home 20081030P</guid></item><item><title>UPDATED RELEASE: Release 1.7 (Oct 30, 2008)</title><link>http://code.msdn.microsoft.com/multitierlinqtosql/Release/ProjectReleases.aspx?ReleaseId=1718</link><description>&amp;#33; Release 1.7&lt;br /&gt;This project is now being hosted over on CodePlex &lt;br /&gt;&amp;#91;url&amp;#58;http&amp;#58;&amp;#47;&amp;#47;www.codeplex.com&amp;#47;MultiTierLinqToSql&amp;#93;&lt;br /&gt;Please get the release from there.&lt;br /&gt;&lt;br /&gt;&amp;#33;&amp;#33; Release notes&lt;br /&gt;&lt;br /&gt;This release contains a number of fixes to the way the GenericObjectDatasource works, mainly to make error handling function correctly. If an error is thrown during an insert or update, the exception is now passed into the Updated or Inserted event of the GenericObjectDatasource, so that it can be handled by client code.&lt;br /&gt;See the Error Handling section of the main page for more details.&lt;br /&gt;&lt;br /&gt;This release has also refactored the code, so that all the generic code is now kept in one assembly GenericDataLayer and the project specific stuff has been moved out into another assembly. This makes it easier to use this code in your projects without having to remove example code from the main project.</description><author></author><pubDate>Thu, 30 Oct 2008 17:02:48 GMT</pubDate><guid isPermaLink="false">UPDATED RELEASE: Release 1.7 (Oct 30, 2008) 20081030P</guid></item><item><title>CREATED RELEASE: Release 1.7 (Oct 30, 2008)</title><link>http://code.msdn.microsoft.com/multitierlinqtosql/Release/ProjectReleases.aspx?ReleaseId=1718</link><description>This project is now being hosted over on CodePlex &lt;br /&gt;&amp;#91;url&amp;#58;http&amp;#58;&amp;#47;&amp;#47;www.codeplex.com&amp;#47;MultiTierLinqToSql&amp;#93;&lt;br /&gt;Please get the release from there.</description><author></author><pubDate>Thu, 30 Oct 2008 16:55:56 GMT</pubDate><guid isPermaLink="false">CREATED RELEASE: Release 1.7 (Oct 30, 2008) 20081030P</guid></item><item><title>NEW POST: Question - Error handling</title><link>http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=322</link><description>&lt;div class="wikidoc"&gt;
Hello beljakm, to answer your question, the way you should handle this is in the OnUpdated/OnInserted event of your GenericObjectDataSource using code like the following:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
 protected void ProductDataSource_Updated(object sender, ObjectDataSourceStatusEventArgs e)
    {
        if (e.Exception != null)
        {
            //litError is a literal control I am using to display the error to the user
            litError.Text = e.Exception.Message;
            e.ExceptionHandled = true;
        }
    }
&lt;/pre&gt; &lt;br /&gt;Basically you check if an exception has occurred, do something with it, probably show the details to the user, and then tell the GenericObjectDatasource that you've handled it. To use this you'll need to get version 1.7 as there was a bug in the way this worked in previous versions.&lt;br /&gt;Note that I'm moving the code over to CodePlex, so you can now use svn to get the latest source, should be easier for everyone!&lt;br /&gt;Rupert&lt;br /&gt;
&lt;/div&gt;</description><author>rbates</author><pubDate>Thu, 30 Oct 2008 16:52:27 GMT</pubDate><guid isPermaLink="false">NEW POST: Question - Error handling 20081030P</guid></item><item><title>NEW POST: Question - Error handling</title><link>http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=322</link><description>&lt;div class="wikidoc"&gt;
Hello,&lt;br /&gt; &lt;br /&gt;I have probably posted my question in the wrong discussion group earlier, so I am re-posting it.  &lt;br /&gt; &lt;br /&gt;rbates - the solution is very elegant, and its evolving.   However, here is a question:&lt;br /&gt; &lt;br /&gt;Where and how do you handle events, e.g. OnLastNameChanged() in your person class? If I extend Person class, as shown below, and an exception is thrown, I keep getting error in GenericObjectDataSourceView because PropertyDescriptor, SetValue property does not handle ArgumentException. Should I somehow handle this in PersonController? Any easy way to get around this?  This based on ScottGu's blog.&lt;br /&gt; &lt;br /&gt;namespace DataLayer&lt;br /&gt;{&lt;br /&gt;public partial class Person&lt;br /&gt;{ &lt;br /&gt;partial void OnLastNameChanged()&lt;br /&gt;{&lt;br /&gt;if (this.LastName==&amp;quot;&amp;quot;)&lt;br /&gt;throw new Exception(&amp;quot;Error: Last Name cannot be empty.&amp;quot;);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;P.S. &lt;br /&gt;The example below is trivial, and it is only for illustrative purposes. I would like to know what is the best way to handle DataContext events.&lt;br /&gt;
&lt;/div&gt;</description><author>beljakm</author><pubDate>Tue, 21 Oct 2008 15:14:43 GMT</pubDate><guid isPermaLink="false">NEW POST: Question - Error handling 20081021P</guid></item><item><title>NEW POST: Using LINQ to sql in three tier architecture with ObjectDataSource and BusinessObject</title><link>http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=591</link><description>&lt;div class="wikidoc"&gt;
I have been rapidly getting into generics, and learning its powers.  Examples shown here are great.  However, here is a question:&lt;br /&gt; &lt;br /&gt;Where and how do you handle events, e.g. OnLastNameChanged() in your person class?  If I extend Person class, as shown below, and an exception is thrown, I keep getting error in GenericObjectDataSourceView because PropertyDescriptor, SetValue property does not handle ArgumentException.  Should I somehow handle this in PersonController? Any easy way to get around this?&lt;br /&gt; &lt;br /&gt;namespace DataLayer&lt;br /&gt;{&lt;br /&gt;    public partial class Person&lt;br /&gt;    {       &lt;br /&gt;        partial void OnLastNameChanged()&lt;br /&gt;        {&lt;br /&gt;            if (this.LastName==&amp;quot;&amp;quot;)&lt;br /&gt;               throw new Exception(&amp;quot;Error: Last Name cannot be empty.&amp;quot;);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;P.S. &lt;br /&gt;The example below is trivial, and it is only for illustrative purposes.  I would like to know what is the best way to handle DataContext events.&lt;br /&gt;
&lt;/div&gt;</description><author>beljakm</author><pubDate>Sat, 18 Oct 2008 15:26:46 GMT</pubDate><guid isPermaLink="false">NEW POST: Using LINQ to sql in three tier architecture with ObjectDataSource and BusinessObject 20081018P</guid></item><item><title>UPDATED RELEASE: Release 1.6.1 (Oct 11, 2008)</title><link>http://code.msdn.microsoft.com/multitierlinqtosql/Release/ProjectReleases.aspx?ReleaseId=1641</link><description>Just an update to 1.6 to replace a missing attribute in the test project&lt;br /&gt;&lt;br /&gt;1.6 release notes&amp;#58;&lt;br /&gt;&lt;br /&gt;This release includes some new classes to support Logging as well as a change to the way that the code functions outside of an asp.net application.&lt;br /&gt;&amp;#33;&amp;#33; Logging&lt;br /&gt;There is now an easy way to configure Linq to Sql&amp;#39;s logging feature &amp;#40;DataContext.Log&amp;#41; 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&amp;#58;&lt;br /&gt;&lt;br /&gt;In the &amp;#60;configSections&amp;#62; element&amp;#58;&lt;br /&gt;&lt;br /&gt;&amp;#60;section name&amp;#61;&amp;#34;GenericDataSection&amp;#34; type&amp;#61;&amp;#34;DataLayer.GenericDataSection, DataLayer&amp;#34; allowDefinition&amp;#61;&amp;#34;MachineToApplication&amp;#34; restartOnExternalChanges&amp;#61;&amp;#34;true&amp;#34; requirePermission&amp;#61;&amp;#34;false&amp;#34;&amp;#47;&amp;#62;&lt;br /&gt;&lt;br /&gt;Then directly after &amp;#60;configSections&amp;#62;&amp;#58;&lt;br /&gt;&lt;br /&gt;&amp;#60;GenericDataSection LogType&amp;#61;&amp;#34;file&amp;#34; LogFile&amp;#61;&amp;#34;C&amp;#58;&amp;#92;Projects&amp;#92;MultiTierLinqToSql_release&amp;#92;test.txt&amp;#34; DeleteExistingFile&amp;#61;&amp;#34;true&amp;#34;&amp;#47;&amp;#62;&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&amp;#58;&lt;br /&gt;&amp;#35; LogType - this can be either &amp;#39;file&amp;#39; &amp;#40;logs output to a file&amp;#41;, &amp;#39;debug&amp;#39; &amp;#40;logs output to Systems.Diagnostics.Debug&amp;#41; or &amp;#39;none&amp;#39; &amp;#40;switches logging off&amp;#41;. &lt;br /&gt;&amp;#35; LogFile - only applies when LogType is set to &amp;#39;file&amp;#39;, and the default is &amp;#39;log.txt&amp;#39; it specifies the name of the file to use for logging.&lt;br /&gt;&amp;#35; DeleteExistingFile - only applies when LogType is set to &amp;#39;file&amp;#39;, values can be &amp;#39;true&amp;#39; or &amp;#39;false&amp;#39;, 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;br /&gt;&lt;br /&gt;&amp;#33;&amp;#33;&amp;#33; Notes&lt;br /&gt;As with all file logging this can be pretty detrimental to performance and so should only be used when debugging.&lt;br /&gt;&lt;br /&gt;To handle the logging to the output window I have used the DebuggerWriter class described here&amp;#58; &amp;#91;url&amp;#58;http&amp;#58;&amp;#47;&amp;#47;www.u2u.info&amp;#47;Blogs&amp;#47;Kris&amp;#47;Lists&amp;#47;Posts&amp;#47;Post.aspx&amp;#63;ID&amp;#61;11&amp;#93;&lt;br /&gt;&lt;br /&gt;&amp;#33;&amp;#33; Changes to DataContext creation outside of Asp.Net apps&lt;br /&gt;For situations where an HttpContext does not exist &amp;#40;ie. where the code is being used outside of a web app&amp;#41; the DataContext is now stored in Thread local storage. See this post &amp;#91;url&amp;#58; https&amp;#58;&amp;#47;&amp;#47;code.msdn.microsoft.com&amp;#47;Thread&amp;#47;View.aspx&amp;#63;ProjectName&amp;#61;multitierlinqtosql&amp;#38;ThreadId&amp;#61;361&amp;#93; for more information.</description><author></author><pubDate>Sat, 11 Oct 2008 10:58:01 GMT</pubDate><guid isPermaLink="false">UPDATED RELEASE: Release 1.6.1 (Oct 11, 2008) 20081011A</guid></item><item><title>CREATED RELEASE: Release 1.6.1 (Oct 11, 2008)</title><link>http://code.msdn.microsoft.com/multitierlinqtosql/Release/ProjectReleases.aspx?ReleaseId=1641</link><description>just an update to 1.6 to replace a missing attribute in the test project</description><author></author><pubDate>Sat, 11 Oct 2008 10:55:12 GMT</pubDate><guid isPermaLink="false">CREATED RELEASE: Release 1.6.1 (Oct 11, 2008) 20081011A</guid></item><item><title>NEW POST: Sorting with IEnumerable data not supported</title><link>http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=749</link><description>&lt;div class="wikidoc"&gt;
&lt;div class="quote"&gt;
 &lt;br /&gt;Tess wrote:&lt;br /&gt;Hello. Great discussion. I ran into a problem with the sample project, however, which I don't see discussed elsewhere. I get the error &amp;quot;data source 'ProductDataSource' does not support sorting with IEnumerable data. Automatic sorting is only supported with DataView, DataTable, and DataSet.&amp;quot;&lt;br /&gt;Did anyone else see that? Fix that?&lt;br /&gt;Cheers,&lt;br /&gt;Tess&lt;br /&gt; &lt;br /&gt;
&lt;/div&gt; &lt;br /&gt;Hi Tess, the fix is to add the attribute SortParameterName=&amp;quot;sortExpression&amp;quot; into the ProductDataSource. I don't know how that got broken in the example project but I'll update it now, thanks for pointing it out.&lt;br /&gt;
&lt;/div&gt;</description><author>rbates</author><pubDate>Sat, 11 Oct 2008 10:46:53 GMT</pubDate><guid isPermaLink="false">NEW POST: Sorting with IEnumerable data not supported 20081011A</guid></item><item><title>NEW POST: Sorting with IEnumerable data not supported</title><link>http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=749</link><description>&lt;div class="wikidoc"&gt;
Hello. Great discussion. I ran into a problem with the sample project, however, which I don't see discussed elsewhere. I get the error &amp;quot;data source 'ProductDataSource' does not support sorting with IEnumerable data. Automatic sorting is only supported with DataView, DataTable, and DataSet.&amp;quot;&lt;br /&gt;Did anyone else see that? Fix that?&lt;br /&gt;Cheers,&lt;br /&gt;Tess&lt;br /&gt;
&lt;/div&gt;</description><author>Tess</author><pubDate>Fri, 26 Sep 2008 17:18:19 GMT</pubDate><guid isPermaLink="false">NEW POST: Sorting with IEnumerable data not supported 20080926P</guid></item><item><title>NEW POST: EntitySet property or seperate controller</title><link>http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=729</link><description>&lt;div class="wikidoc"&gt;
I'd definitely go for option 1. Not that there's anything particularly wrong with option 2 it's just more code for no gain. Also if the child table only makes sense in the context of the parent table then it's better practice to deal primarily with that table.&lt;br /&gt;
&lt;/div&gt;</description><author>rbates</author><pubDate>Sun, 21 Sep 2008 19:35:04 GMT</pubDate><guid isPermaLink="false">NEW POST: EntitySet property or seperate controller 20080921P</guid></item><item><title>NEW POST: Question - Error handling</title><link>http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=322</link><description>&lt;div class="wikidoc"&gt;
Hi rbates, I was thinking the same thing by implementing a static close method or alike dispose of the datacontext by request.&lt;br /&gt; &lt;br /&gt;It is a little more verbose, but if I could overcome my other requirement using the static implementation then I would go with the static approach, however I cannot think of another way of doing this, unless you have some suggestions?  I need to be able to use a controller(s) dynamically to insert and update (using reflection and configuration), i'm using your GenericController as the data layer component of a larger generic application i am working on.&lt;br /&gt; &lt;br /&gt;The idea is to feed my generic business components with a controller (based on the GenericController class and an interface I have implemented) and using reflection I create/insert/update entities regardless of the type.  I haven't been able to figure out a way to do this with the static approach, any ideas?&lt;br /&gt; &lt;br /&gt;I've attached the interface I have implemented, which basically just enforces additional overloads to create and insert entity objects without having to know the type at compile time.  I couldn't think of any other way to go about doing this without knowing the types at compile time.  I've implemented CreateEntity methods in the GenericController class to create, insert and return the correct entity, including non-generic methods.&lt;br /&gt; &lt;br /&gt;I would appreciate your thoughts on what I have done and if you think I should/could have done things different/better.&lt;br /&gt; &lt;br /&gt;Cheer&lt;br /&gt;TC&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;    public interface IController&lt;br /&gt;    {&lt;br /&gt;        void Insert(object entity);&lt;br /&gt;        ...&lt;br /&gt;   &lt;br /&gt;        object CreateObject();&lt;br /&gt;        ...&lt;br /&gt; &lt;br /&gt;        void SubmitChanges();&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    public class GenericController&amp;lt;TEntity, TDataContext&amp;gt; : IController, IDisposable ...&lt;br /&gt;    {&lt;br /&gt;        ...&lt;br /&gt;        ...&lt;br /&gt;        ...&lt;br /&gt; &lt;br /&gt;        public void Insert(object entity)&lt;br /&gt;        {&lt;br /&gt;            Insert(entity as TEntity)&lt;br /&gt;        }&lt;br /&gt; &lt;br /&gt;        public TEntity CreateEntity()&lt;br /&gt;        {&lt;br /&gt;            TEntity entity = new TEntity();&lt;br /&gt;            Insert(entity)&lt;br /&gt; &lt;br /&gt;            return entity;&lt;br /&gt;        }        &lt;br /&gt; &lt;br /&gt;        public object CreateObject() // Same as CreateEntity but couldn't overload because of existing definition&lt;br /&gt;        {&lt;br /&gt;            return CreateEntity() as object;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;
&lt;/div&gt;</description><author>tc</author><pubDate>Thu, 18 Sep 2008 05:05:30 GMT</pubDate><guid isPermaLink="false">NEW POST: Question - Error handling 20080918A</guid></item><item><title>NEW POST: How to use in NON ASP.NET code sections?</title><link>http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=361</link><description>&lt;div class="wikidoc"&gt;
Hi, &lt;br /&gt; &lt;br /&gt;Thanks for the framework - very helpful!&lt;br /&gt; &lt;br /&gt;It would be handy to be able to undo changes made to the datacontext in non-asp.net applications.  As far as I can see there is no way to discard changes made to tables in a datacontext without destroying it.  What about a method in the genericcontroller to destroy the datacontext, so then the next time a DataContext is called a new one is created?&lt;br /&gt; &lt;br /&gt;Thanks,&lt;br /&gt;David.&lt;br /&gt;
&lt;/div&gt;</description><author>DavidB</author><pubDate>Thu, 18 Sep 2008 01:46:07 GMT</pubDate><guid isPermaLink="false">NEW POST: How to use in NON ASP.NET code sections? 20080918A</guid></item><item><title>NEW POST: Question - Error handling</title><link>http://code.msdn.microsoft.com/multitierlinqtosql/Thread/View.aspx?ThreadId=322</link><description>&lt;div class="wikidoc"&gt;
Hi tc, I think the approach you suggest is fine, it makes the code a bit more verbose but that's just a cosmetic thing really. Another thought I had would be to allow the calling code to tell the controller to dispose of the datacontext when it needed to, this would be useful in a number of other scenarios as well so I'll probably add it in at some point.&lt;br /&gt;
&lt;/div&gt;</description><author>rbates</author><pubDate>Wed, 17 Sep 2008 15:31:51 GMT</pubDate><guid isPermaLink="false">NEW POST: Question - Error handling 20080917P</guid></item></channel></rss>