Click here to Skip to main content
15,867,488 members
Articles / Database Development / SQL Server

LINQ to SQL Database Synchronizer

Rate me:
Please Sign up or sign in to vote.
4.96/5 (14 votes)
1 Jun 2009Ms-PL4 min read 84K   1.4K   72   16
An open source utility that synchronizes your database structure with a LINQ to SQL model.

Introduction

LINQ to SQL Database Synchronizer (csdb.exe) is a tool that provides database structure synchronization from a LINQ to SQL model. It supports both creating new databases and updating existing ones. It is important to note that this tool never deletes any data or structure; it simply adds missing tables, columns and indexes and modifies existing columns.

Main Benefits

  • Single click O\R model synchronization
  • Better team productivity, streamline database changes between your team members
  • Easier product installations and upgrades, no complicated SQL scripts needed
  • Simpler maintenance of a single model instead of two

Background

The LINQ to SQL Framework provides a simple and convenient way to communicate with databases, using simple C# classes and LINQ, without writing any sophisticated SQL commands. While working with it, I've stumbled upon a major drawback: The DataContext.CreateDatabase method only supports creating new databases. This means that in order to modify an existing LINQ to SQL model over an existing database, one must apply the structure changes manually on the database, or delete the database entirely and invoke the CreateDatabase method again. This drawback may really slow a team down, when each member of the team has his own database for testing, every feature that another member adds that requires a database structure change, forces the other members to run various scripts or perform manual changes on their own database. The same goes for live servers that need to be updated with a new product version.

The DataContext.CreateDatabase method I've mentioned earlier uses SQL scripts to create the database and the tables inside it. This tool uses the SQL Server Management Objects (SMO) library instead. It analyzes a LINQ to SQL model, compares it to an existing database structure and finally applies all of the necessary changes to the database structure.

Inside the Code

We basically have two models we want to synchronize - one is the LINQ to SQL model, and the other is the database model. So let's start off by loading the LINQ to SQL model:

C#
var asm = Assembly.LoadFrom(Options.AssemblyFile);       //Load an assembly file
var type = asm.GetType(Options.TypeName, true);          //Find the DataContext class
						  //using reflection
var model = new AttributeMappingSource().GetModel(type); //Load the LINQ to SQL mapping
                                                         //model from the specified type

Review this in an online IDE here and here.

Now, we'll load the database model using SMO and the connection string we have.

C#
var sb = new SqlConnectionStringBuilder(ConnectionString);   //Parse the 
						      //connection string
var server = new Server(sb.DataSource);                      //Connect to the 
                                                             //database server
var db = server.Databases[sb.InitialCatalog];                //Get the database

Review this in an online IDE here and here.

Now we have all the data we need, and it's simply a matter of iterating the LINQ to SQL model, and locating the corresponding database objects. If they don't exist, we simply create them, otherwise we verify their definition.

C#
foreach (MetaTable table4 in model.GetTables())
{
  string schemaName;
  string tableName;
  ParseFullTableName(mt.TableName, out schemaName, out tableName);  //Split the schema 
							    //and table name
  var table = Database.Tables[tableName, schemaName];               //Find the table
  if (table == null)                                                //If the table 
                                                                    //doesn't exist
  {
    table = new Table(Database, tableName, schemaName);             //Create the table
    Database.Tables.Add(table);
  }
  //Now we can synchronize the table columns...
}

Review this in an online IDE here and here.

Using the Code

This tool works as a simple command line tool (*.exe), simply specify an assembly and a type name of a LINQ to SQL DataContext class and run it, your database structure will be synchronized by this model.

Prerequisites

This tool uses SQL Server Management Objects (SMO), the latest version of it can be found at the Microsoft SQL Server 2008 Feature Pack download page, but here are the direct links:

Usage

This tool is used like any standard command line tool, with the following syntax:

csdb.exe /assembly:[AssemblyFile] /type:[TypeName] /autocreate 
	/autoupdate /cs:[ConnectionString] /dbfilename:[DatabaseFilename]
	
  /assembly:[AssemblyFile]    The assembly filename that contains the LINQ to SQL
			   (http://msdn.microsoft.com/en-us/library/bb425822.aspx) 
			   DataContext class, e.g.: bin\debug\MyApp.exe
  /type:[TypeName]            Optional, The type name of the LINQ to SQL
			   (http://msdn.microsoft.com/en-us/library/bb425822.aspx) 
			   DataContext class, e.g.: MyApp.MyDataContext. 
			   if not provided, 
			   any class that inherits from the DataContext 
			   class will be processed.
  /autocreate                 When specified, the tool will create the database 
			   if it doesn't exist.
  /autoupdate                 When specified, the tool will update the existing 
			   database structure.
  /cs:[ConnectionString]      Optional, The connection string of the database 
			   to be synchronized, if not provided, the default 
			   connection string will be used if it exists 
			   in your settings.
  @[Arguments Filename]       Read the command line arguments from an 
			   external text file.

Example

This statement will synchronize (create and update) the MyDb database in the local machine's SqlExpress instance using the MyApp.MyDataContext class located in the MyApp.exe assembly.

csdb.exe /assembly:"bin\debug\MyApp.exe" /type:"MyApp.MyDataContext" 
	/autocreate /autoupdate /cs:"Data Source=.\SQLEXPRESS;Initial 
	Catalog=MyDb;Integrated Security=True"

Recommendations

  • Specify both the /autocreate and /autoupdate options for maximum automation.
  • Create a batch file that executes this tool, and include it in your project.
  • In the early stages of development, run this batch file as a post-build step in your project file.

Running the Sample

The sources include a sample project with a LINQ to SQL model of the well known Northwind database. To run the sample:

To change the LINQ to SQL model and synchronize the database:

  • Modify the LINQ to SQL model by modifying the MyNorthwind.dbml file using Visual Studio, you can add a column, add a table, change the data type of a column, allow nulls on a column, etc...
  • Build the Samples project to reflect your changes.
  • Run the SyncMyNorthwindDb.bat batch file to synchronize your database.

Points of Interest

I think that this tool answers a basic need when using the LINQ to SQL Framework. We use it extensively at CodeRun in both development and deployment. In this way, modifying the database is as simple as adding a property.

History

  • 2nd June, 2009: Initial version

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)


Written By
Architect SharpKit
Israel Israel
Founder of SharpKit

Comments and Discussions

 
GeneralAn Easier Way to synchronize database table updates using LINQ Pin
BobRI29-Apr-11 4:59
BobRI29-Apr-11 4:59 
GeneralMy vote of 5 Pin
mobtadi12-Dec-10 3:12
mobtadi12-Dec-10 3:12 
GeneralMy vote of 5 Pin
Bill Do2-Nov-10 18:44
Bill Do2-Nov-10 18:44 
Good
GeneralSome key improvements [modified] Pin
Alphons van der Heijden4-Jun-10 8:43
professionalAlphons van der Heijden4-Jun-10 8:43 
QuestionDate type "Time" not supported? Pin
Alexander Quinte17-Mar-10 12:18
Alexander Quinte17-Mar-10 12:18 
AnswerRe: Date type "Time" not supported? Pin
Alexander Quinte27-Mar-10 1:40
Alexander Quinte27-Mar-10 1:40 
GeneralMore problems... Pin
lexugax11-Feb-10 23:29
lexugax11-Feb-10 23:29 
GeneralRe: More problems... Pin
Dan-el Khen11-Feb-10 23:39
Dan-el Khen11-Feb-10 23:39 
GeneralRe: More problems... Pin
lexugax11-Feb-10 23:57
lexugax11-Feb-10 23:57 
GeneralProblems when using external database server Pin
lexugax2-Feb-10 23:58
lexugax2-Feb-10 23:58 
GeneralRe: Problems when using external database server Pin
lexugax5-Feb-10 4:37
lexugax5-Feb-10 4:37 
GeneralProblem with nvarchar(MAX) Pin
Linosoft25-Nov-09 7:50
Linosoft25-Nov-09 7:50 
GeneralRe: Problem with nvarchar(MAX) Pin
Dan-el Khen25-Nov-09 8:14
Dan-el Khen25-Nov-09 8:14 
GeneralMuchas Gracias and Thank You 10x Pin
Clinton Gallagher6-Jun-09 5:54
professionalClinton Gallagher6-Jun-09 5:54 
GeneralDitto Pin
Nicholas Butler1-Jun-09 11:26
sitebuilderNicholas Butler1-Jun-09 11:26 
GeneralNice Pin
Member 27270981-Jun-09 7:15
Member 27270981-Jun-09 7:15 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.