LINQ to SQL : Start with a good foundation by defining a custom DataContext

This is my first post in a what will become a series of posts on LINQ to SQL. As the title of my blog suggests, I'm going to be "thinking out loud" as I write these and I'm hoping for feedback from others on the pro's and con's of the approaches I'm suggesting. That said, the point of this series of posts will be to define a loose set of best practices around developing with LINQ to SQL in an ASP.Net web environment. The first couple posts will be pretty simplistic but I wanted to get these in place first so I can refer to the concepts later without having to go into detail.

On with the topic at hand...

When starting a new project with LINQ to SQL, it's a good idea to wrap the DataContext with your own class that inherits from the DataContext generated by the designer (or SQLMetal).

Before we do that though, let's take a small step back and talk about namespaces. In the designer, if you click on design surface background, you'll select the DataContext. In the properties window there will be two entries related to namespaces. One is the Context Namespace and the other is the Entity Namespace. Typically you'd put both the generated DataContext and the entity classes within the same namespace, but since we're going to be creating our own DataContext that inherits from the one that is generated for us, I'd suggest that we set these up with different namespaces.

I like to have my data layer to have its own namespace and as such I tend to go with a DB.such_and_such namespace where such_and_such is the name of our database or other logical context name. I'll be using the northwind database for this series of posts, so the logical namespace name is DB.NW. This is what we should put in the Entity Namespace property, but for the Context Namespace, we should set the value to DB.NW.Base to leave room for our custom version in the DB.NW namespace. With our DataContext's name set as simply DataContext as well, we'll get the following generated for us by the designer...

namespace DB.NW.Base
{
    ...
    public partial class DataContext : System.Data.Linq.DataContext
    {
    ...
    }

}
namespace DB.NW
{
    ...
    [Table...]
    public partial class table_name... etc.
}

Next we need to create a new class file in app_code. In this case I'll keep the name the same as the namespace it contains and go with DB.NW.cs.

using System;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Linq;
using System.Runtime.Serialization;
using System.Reflection;

namespace DB.NW
{
    public class DataContext : DB.NW.Base.DataContext
    {
    }
}

Now, it may seem silly at this point to go through all this but doing this now, even with no custom or overridden methods, will save us from having to change our code later that when we need to override methods such as SubmitChanges()..

Published Friday, September 28, 2007 12:43 AM by bschooley
Filed under:

Comments

# re: LINQ to SQL : Start with a good foundation by defining a custom DataContext

Monday, November 19, 2007 11:38 AM by Alan

i have the dot net 3 framework and was looking to play with Linq but can not find what namespace to use and can not see it in system or system.data

# re: LINQ to SQL : Start with a good foundation by defining a custom DataContext

Wednesday, June 04, 2008 12:18 PM by Nick Hauenstein

@Alan:

Linq is in System.Core

# re: LINQ to SQL : Start with a good foundation by defining a custom DataContext

Thursday, July 03, 2008 7:59 AM by Webys

I have a little problem I'm a beginner in LINQ to SQL and I've follow the tutorial from ScottGu's blog: weblogs.asp.net/.../linq-to-sql-part-5-binding-ui-using-the-asp-linqdatasource-control.aspx

All was ok I use VS 2008 (I've converted from VB.NET to C# , I use C#) but when I wish to put the code from App_Code in an sub dir like DAL or BLL (for extensibility of entities like products with partial clases) and generate again the dblm file I've receiving en error:

1. first in my BLL dir from App_Code:

  public partial class Product

   {

       partial void OnValidate(System.Data.Linq.ChangeAction action)

       {

           if (action == ChangeAction.Update && this.Discontinued == true && this.UnitsOnOrder > 0)

           {

               throw new ArgumentException("Record level can't be grather than 0 if Product is Discontinued");

           }

       }

}

and I've included the namespace : using DAL;

... but still error message is :No defining declaration found for implementing declaration of partial method 'Product.OnValidate(System.Data.Linq.ChangeAction)'

2  If i comment all BLL code from my extensibility partial class Product I receive an general error:

Could not load type 'NorthwindDataContext'.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Web.HttpException: Could not load type 'NorthwindDataContext'.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[HttpException (0x80004005): Could not load type 'NorthwindDataContext'.]

  System.Web.Compilation.BuildManager.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase) +565

  System.Web.UI.WebControls.LinqDataSourceView.get_ContextType() +68

[InvalidOperationException: Could not find the type specified in the ContextTypeName property of LinqDataSource 'CategoryLinqDS'.]

  System.Web.UI.WebControls.LinqDataSourceView.get_ContextType() +193

  System.Web.UI.WebControls.LinqDataSourceView.CreateContextAndTable() +458

  System.Web.UI.WebControls.LinqDataSourceView.EnsureContextAndTable(Boolean selecting) +39

  System.Web.UI.WebControls.LinqDataSourceView.ExecuteSelect(DataSourceSelectArguments arguments) +421

  System.Web.UI.WebControls.ListControl.OnDataBinding(EventArgs e) +92

  System.Web.UI.WebControls.ListControl.PerformSelect() +31

  System.Web.UI.WebControls.BaseDataBoundControl.DataBind() +70

  System.Web.UI.WebControls.BaseDataBoundControl.EnsureDataBound() +82

  System.Web.UI.WebControls.ListControl.OnPreRender(EventArgs e) +26

  System.Web.UI.Control.PreRenderRecursiveInternal() +86

  System.Web.UI.Control.PreRenderRecursiveInternal() +170

  System.Web.UI.Control.PreRenderRecursiveInternal() +170

  System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2041

--------------------------------------------------------------------------------

Version Information: Microsoft .NET Framework Version:2.0.50727.1433; ASP.NET Version:2.0.50727.1433

Thanks in advance guys. :)

Leave a Comment

(required) 
(required) 
(optional)
(required)