Using the Linq to Sql Adapter in a DotNetNuke Module

In a previous entry, I discussed a potential solution to a longstanding problem.  The DotNetNuke CMS framework allows declaration of an object qualifier and database owner on a per-installation basis.  This effectively varies the fully-qualified database entity names at runtime.  Because the Linq to Sql system by default utilizes a class attribution approach, it does not lend itself well to such runtime adaptation.

Here I describe the steps necessary to use Linq to Sql within a DotNetNuke module in a reliable, distributable manner.

1. Connect to your DotNetNuke database and add a set of Linq to Sql classes to your project

There exist thousands of tutorials regarding this part of the process.  I suggest starting out with Scott Guthrie’s excellent introduction

2. Download the DotNetNuke Linq to Sql Model Adapter

The model adapter is located on the CodePlex project site and may be downloaded here.  The debug and release versions will contain a single assembly (BrandonHaynes.ModelAdapter.dll); copy this library to your project directory and include a reference to it in your project.

A sample module (source and install versions) and additional documentation are also available on the CodePlex site.

3. Update your DataContext to derive from BrandonHaynes.ModelAdapter.DotNetNukeDataContext

To use the adapter, you must change the base class of your DataContext to the specialized DotNetNuke adapter.  This is most easily accomplished by opening your Linq to Sql classes, right-clicking anywhere within the designer area, and selecting “Properties.”

Locate the Base Class line and change to “BrandonHaynes.ModelAdapter.DotNetNukeDataContext”.  Since the adapter will automatically override the connection string specified in your DataContext properties, I suggest leaving the original value therein.  Doing so will cause a parameterless constructor to be automatically generated, preventing you from being required to supplying a useless connection string during instantiation.

A DataContext with base class changed to use the DotNetNuke adapter.

4. Compile and Enjoy!

That’s all there is to it.  At runtime, the adapter will automatically detect the existing metamodel constructed by your metasource (by default via attributes on your classes, properties, and members) and adjust them to reflect the DotNetNuke object qualifier and database owner.  No further intervention is required by the developer.

Closing Comments

This project is the result of an informal experiment; having heard that runtime meta-model manipulation was not possible, I wanted to verify and determine if this was indeed the case.  I expect that issues will arise, and would appreciate feedback about implementation experiences.  I am particularly interested in hearing from anyone who is actually successful using this library.  Specific issues should be logged in the CodePlex issue tracker.

B

Be Sociable, Share!

5 Comments

  1. DaCoder

    February 13, 2009 @ 12:46 pm

    1

    Hi Brandon
    Thank you for the adapter you developed. I used it for developing a module and it works fine in development.
    My question is, about packaging? What files should I be packaging when deploying this module ?
    I am getting an error like “TypeName used in LinqDataSource not found”? when trying to install this module on a new DNN installation.

    Thanks
    DaCoder

  2. Brandon Haynes

    February 18, 2009 @ 10:19 am

    2

    Hi DaCoder,

    Look on the CodePlex site under the “Releases” tab for a sample installable DotNetNuke module. If you are having issues with deployment, I would use the manifest contained therein as a model for your own module. Note that it was designed for the 4.x line, so you may or may not want to tackle updating the manifest to the 5.0 version.

    Really the only file that is *required* to be deployed is the Linq adapting assembly BrandonHaynes.ModelAdapter.dll. But the target DotNetNuke installation must be configured to use Linq (in 5.x+ this can be performed automatically; if not, see Michael Washington’s LinqPrep tool), and you must be sure to recreate the database schema with fidelity to your development environ.

    The error you describe may be a result of an issue with schema recreation, though it would be more helpful to see a full call stack for the exception.

    I am aware of a number of module deployments utilizing the model adapter, so it is indeed possible. Good luck!

  3. Rex Henderson

    May 6, 2009 @ 7:53 pm

    3

    Hi Brandon,
    Fabulous bit of code you created.

    During testing I noticed my GetModel() call was throwing exception due to flaws in my MappingSource graph. These poor MappingSource objects were getting cache all the same. Being a static class field, you had to bump the web.config to clear it. What I did was add the MappingSource after a successful GetModel call to remove this minor obstacle.

    FYI – I extended the adapter down to the MemberData
    I use it to look up defaults from the sys.default_constraints table and set my MetaDataMember.Expression so I do not have to explicitely set values on those columns for new records. Works like a charm.

    The best part is, using your foundation, I do not have to touch the auto-generated dbml code AT ALL for any of my tweaking needs.

    Let me know if you’re interested in see my additions. Thanks!

  4. Brandon Haynes

    May 8, 2009 @ 8:52 am

    4

    Hi Rex,

    I appreciate the feedback you’ve been able to provide. I actually have been considering packaging the project into a more generalized LINQ to SQL runtime model adaption engine, so I would be interested in seeing what you’ve done. I will be in touch.

    B

  5. Tim Losser

    June 8, 2011 @ 5:38 pm

    5

    Hi Brandon, everybody,

    First off, thanks for this…very nice and a million times better than the core DNN db approach.

    One thing I’d struggled with when trying to deploy was whether to create my initial tables with or without the object qualifier…it isn’t noted here but I found some helpful info on the Codeplex page:

    Important
    Module developers must develop against a DotNetNuke installation with no object qualifier. This adapter does not store the design-time object qualifier for later removal. Any design-time database owner may be used; the design-time value is removed via a regular expression.

    I just wanted to add this in here for anybody who hadn’t thought of checking on the CodePlex site and was struggling to figure this part out.

    Thanks again,
    Tim

Log in