CodeSmith template to generate LINQ To SQL Data Context

If you are interested in what LINQ to SQL generates and don’t have Orcas installed or available right now but use CodeSmith try the following template to generate very similar code.

The primary difference is that this writes out the System types rather than the C# aliases (e.g. System.Int32 instead of int) but that could easily be changed but is binary compatible and otherwise almost identical to the source.

Download LINQ to SQL template (CodeSmith) (4 KB)

<%@ CodeTemplate Src="LinqFunctions.cs" Inherits="LinqFunctions" Language="C#" TargetLanguage="C#"
  Description="Generates a data context and entities for given tables." %>
<%@ Assembly Name="SchemaExplorer" %>
<%@ Assembly Name="System.Data" %>
<%@ Import Namespace="SchemaExplorer" %>
<%@ Import Namespace="System.Collections.Generic" %>
<%@ Import Namespace="System.Data" %>
<%@ Property Name="DataContextClassName" Type="System.String" Category="Naming" Optional="True"Description="Name of the data context class to generate." %>
<%@ Property Name="Namespace" Type="System.String" Category="Naming" Optional="True" Description="Namespace for the data context class to generate." %>
<%@ Property Name="SourceTables" Type="SchemaExplorer.TableSchemaCollection" Category="Connection"Description="Tables to be mapped." %>
<%SchemaExplorer.DatabaseSchema database = SourceTables[0].Database;
string className = (String.IsNullOrEmpty(DataContextClassName)) ? DatabaseName(database) + "DataContext" : DataContextClassName;
Dictionary<TableSchema, List<TableKeySchema>> reverseForeignKeys = new Dictionary<TableSchema, List<TableKeySchema>>();
foreach(TableSchema table in SourceTables) {
    foreach(TableKeySchema keySchema in table.ForeignKeys) {
        if (reverseForeignKeys.ContainsKey(keySchema.PrimaryKeyTable)) {
            reverseForeignKeys[keySchema.PrimaryKeyTable].Add(keySchema);
        }
        else {
            List<TableKeySchema> keySchemas = new List<TableKeySchema>();
            keySchemas.Add(keySchema);
            reverseForeignKeys.Add(keySchema.PrimaryKeyTable, keySchemas);
        }
    }
}%>//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     CodeSmith template DeLINQuent.cst v0.1
//     Generated by <%=CurrentUserName()%> at <%=DateTime.Now%>
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace <%=Namespace%>{
    public partial class <%=className%> : global::System.Data.Linq.DataContext
    {
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public <%=className%>(string connection) :
                base(connection)
        {
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public ProjectDataContext(global::System.Data.IDbConnection connection) :
                base(connection) {
        }
<%    foreach(TableSchema table in SourceTables) {
        string entityName = EntityName(table);
        string propertyName = TableName(table);%>
        public global::System.Data.Linq.Table<<%=entityName%>> <%=propertyName%> {
            get {
                return this.GetTable<<%=entityName%>>();
            }
        }
<%     } %>
    }<%    foreach(TableSchema table in SourceTables) {
        string entityName = EntityName(table);%>
    [global::System.Data.Linq.Table(Name="<%=table.FullName%>")]
    public partial class <%=entityName%> :global::System.Data.Linq.INotifyPropertyChanging,global::System.ComponentModel.INotifyPropertyChanged
    {
<%    foreach(ColumnSchema column in table.Columns) { %>
        private <%=NullableSystemType(column)%> _<%=PropertyName(column)%>;
<%    }
      if (table.ForeignKeys.Count > 0) { %>
<%        foreach(TableKeySchema keySchema in table.ForeignKeys) {
            string foreignEntityName = EntityName(keySchema.PrimaryKeyTable);%>
        private global::System.Data.Linq.EntitySet<<%=foreignEntityName%>> _<%=foreignEntityName%>;<%
          }
      }
      if (reverseForeignKeys.ContainsKey(table)) { %>
<%        foreach(TableKeySchema keySchema in reverseForeignKeys[table]) {
            string propertyName = TableName(keySchema.ForeignKeyTable);%>
        private global::System.Data.Linq.EntityRet<<%=EntityName(keySchema.ForeignKeyTable)%>> _<%=propertyName%>;
<%        }
      } %>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public <%=entityName%>() {
        }
<%    foreach(ColumnSchema column in table.Columns) {
        string propertyName = PropertyName(column);%>
        [global::System.Data.Linq.Column(Storage="_<%=propertyName%>", Name="<%=column.Name%>", DBType="<%=AttributeColumnDbType(column)%>"<%
            if (column.IsPrimaryKeyMember) { %>, IsPrimaryKey=true<% }
            if (!column.AllowDBNull) { %>, CanBeNull=false<% } %>)]
        public <%=NullableSystemType(column)%> <%=propertyName%> {
            get {
                return this._<%=propertyName%>;
            }
            set {
                if (this._<%=propertyName%> != value) {
                    this.OnPropertyChanging("<%=propertyName%>");
                    this._<%=propertyName%> = value;
                    this.OnPropertyChanged("<%=propertyName%>");
                }
            }
        }

<%    } %>
<%    foreach(TableKeySchema keySchema in table.ForeignKeys) {
        string propertyName = EntityName(keySchema.PrimaryKeyTable);
        string tableName = TableName(keySchema.PrimaryKeyTable);%>
        [global::System.Data.Linq.Association(Name="<%=keySchema.Name%>",
            Storage="_<%=propertyName%>", OtherKey="<%=AttributeColumnList(keySchema.ForeignKeyMemberColumns)%>",
            ThisKey="<%=AttributeColumnList(keySchema.PrimaryKeyMemberColumns)%>", IsForeignKey=true)]
        public <%=propertyName%> <%=propertyName%> {
            get {
                return this._<%=propertyName%>.Entity;
            }
            set {
                if (this._<%=propertyName%>.Entity != value) {
                    this.OnPropertyChanging("<%=propertyName%>");
                    if ((this._<%=propertyName%>.Entity != null)) {
                        <%=propertyName%> temp = this._<%=propertyName%>.Entity;
                        this._<%=propertyName%>.Entity = null;
                        temp.<%=TableName(table)%>.Remove(this);
                    }
                    this._<%=propertyName%>.Entity = value;
                    if ((value != null)) {
                        value.<%=TableName(table)%>.Add(this);
                    }
                    this.OnPropertyChanged("<%=propertyName%>");
                }
            }
        }
<%    } %>
<%    if (reverseForeignKeys.ContainsKey(table)) {
        foreach(TableKeySchema keySchema in reverseForeignKeys[table]) {
            string propertyName = TableName(keySchema.ForeignKeyTable);%>
        [global::System.Data.Linq.Association(Name="<%=keySchema.Name%>",
            Storage="_<%=propertyName%>", OtherKey="<%=AttributeColumnList(keySchema.PrimaryKeyMemberColumns)%>",
            ThisKey="<%=AttributeColumnList(keySchema.ForeignKeyMemberColumns)%>")]
        public IEnumerable<<%=EntityName(keySchema.ForeignKeyTable)%>> <%=propertyName%> {
            get {
                return this._<%=propertyName%>;
            }
        }

<%             }
        } %>
        public event global::System.ComponentModel.PropertyChangedEventHandler PropertyChanging;
        public event global::System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        protected void OnPropertyChanging(string propertyName) {
            if (this.PropertyChanging != null)
                this.PropertyChanging(this, new global::System.ComponentModel.PropertyChangedEventArgs(propertyName));
        }

[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        protected void OnPropertyChanged(string propertyName) {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new global::System.ComponentModel.PropertyChangedEventArgs(propertyName));
        }
    }
<%     } %>
}

[)amien

2 responses

  1. Avatar for steve

    Cool.

    The DebuggerNonUserCodeAttribute makes me shudder though - asking to hide code from the debugger just seems like asking someone to kick you in the nuts. What's wrong with just using 'step over' (or equivalent) when you don't wanna see something? Or defining a visibility mask in the debugger session (typical Eclipse way)? Hiding stuff from the debugger statically in the code itself just gives me horrible nightmares of debugging VB6 and knowing there's something wrong happening in between the lines that you can't see...

    steve 26 June 2007
  2. Avatar for steve

    Unless that doesn't actually hide it but just categorises it for filtering? MSDN is pretty damn vague on the whole thing (shock) and I've not had to debug .Net much before...

    steve 26 June 2007