|
Note: This is an unedited contribution. If this article is inappropriate,
needs attention or copies someone else's work without reference then please
Report This Article
Title: Creating a DAL with Subsonic
Author: Michael Ceranski
Language: C#, VB.NET
Platform: Windows, .NET 2.0
Technology: ADO.NET
Level: Beginner
Description: How to create a DAL using Subsonic
Download SubsonicDAL_src.zip - 302.9 KB
Introduction
In a typical data driven application you can expect to spend at least 40-50% of your time writing the "CRUD" code (Create, Read, Update and Delete). In order to loosely couple your application code with the database you will probably want to create a DAL (Data Access Layer). Unfortunately, writing a DAL can be very time consuming. Especially if you are working on a project where the data model is constantly evolving.
Well lucky for us there is SubSonic. SubSonic is an open source tool built for .NET that will automatically build your DAL with a few simple steps.
Building the DAL
- The first task is to download and install SubSonic from http://www.subsonicproject.com.
- Open up Visual Studio 2005 and create a new project. Choose Visual C# --> Windows --> Windows Control Library.
- Once the project is created you need to add 3 references. The first is to the SubSonic.dll. If you did a default install then this should be located at C:\Program Files\SubSonic\SubSonic 2.0.3\SubSonic.dll. You will also need a reference to System.Web (unfortunately this is a requirement) and System.Configuration.
- Now you need to add an application configuration file. In the config file you will need to add a connection string, a config section and a provider section. Here is sample "SubSonic" configuration file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="SubSonicService"
type="SubSonic.SubSonicSection, SubSonic" requirePermission="false"/>
</configSections>
<connectionStrings>
<add name="AdventureWorks" connectionString="Data Source=.;Database=AdventureWorks;Integrated Security=true;"/>
</connectionStrings>
<SubSonicService defaultProvider="AdventureWorks">
<providers>
<clear/>
<add name="AdventureWorks" type="SubSonic.SqlDataProvider, SubSonic" connectionStringName="AdventureWorks" generatedNamespace="AdventureWorksDAL"/>
</providers>
</SubSonicService>
</configuration>
Note: You can change the default namespace by modifying the generatedNamespace attribute
- Add a new folder to the solution with the name "Generated". This is where all of the generated code will get created. Although it is not required to add this folder it is definately recommended. The folder is nice to have because once you are happy with the data model and the resulting code you can move it into a separate folder that will be your "production ready" code. Since SubSonic is a code generation tool you may choose to generate the files a few times and keep overwriting the source files in the "Generated" folder without affecting the "production ready" files. When the files are generated they do not get automatically included into the library so having this extra folder filled with files will not bloat your DLL. This is because Visual Studio will ignore files that are not included in the project and therefore those files will not get compiled into the assembly.
- Now its time to run sonic.exe. If you did a default install, sonic.exe will be located at C:\Program Files\SubSonic\SubSonic 2.0.3\SubCommander\sonic.exe. The easiest way to run sonic.exe is to add it as an external tool to your VS2005 environment. This can be done by going to Tools-->External Tools and clicking on the "Add" button. In the Title field I entered "SubSonic DAL" but you can name it whatever you like. In the command field enter in the path to the sonic.exe. In the Arguments field enter in "generate /out Generated". This means that all generated code will get created in the folder named Generated that we created in the previous step. Finally, set the Initial Directory to "$(ProjectDir)". Also check the "Use Output Window" and the "Prompt for Arguments" checkboxes. Click the "OK" button to close out the dialog.
- Now for the moment of truth. Execute sonic.exe by clicking on the "SubSonic DAL" menu item under the "Tools" menu. Keep an eye on the output window so you can see the execution status. If you setup something wrong the output window will usually give you a clue of how to fix the error.
- If everything went well, you should see a bunch of new files in the generated folder. If you do not see any files than you may need to click on the show all files button located at the top of the solution explorer. Select all of the files, right click and choose "Include In Project". Now compile and voila! You have just created your first SubSonic DAL!

Using the DAL
So now you have officially created your first SubSonic DAL. Now you are probably wondering...how do I use this thing? Well here are some sample code snippets.
Sample No. 1 - Fetching all of the products that have a ListPrice greater than $50.00, a Class value of L and is the Color Yellow
Query qry = Product.CreateQuery().WHERE("ListPrice > 50.00").AND("Class = L").AND("Color = Yellow");
IDataReader rdr = qry.ExecuteReader();
while (rdr.Read()) {
Console.WriteLine(rdr[Product.Columns.Name].ToString());
}
Notice how I chained the where conditions!
Sample No. 2 - Adding a new product
Currency c = new Currency();
c.CurrencyCode = "CPD";
c.Name = "Code Project Dollar";
c.Save("Some_UserName");
-
Tips & Thoughts
If you need to extend the functionality of a class then use partial classes. This way when you re-generate the files you won't have to worry about having your custom code overwritten.
This product states that it works with other database systems. This library could be very useful if you are creating an application that runs against multiple database systems. In theory, with a little work and some basic know-how you should be able to move your application from SQL Server to Oracle without changing your code. You would simply just recompile your DAL against the new RDBMS (Remote Database Management System). Remember, I said in theory! Don't send me hate emails if this does not work.
Finally, SubSonic is not only a big time saver but it is free, it is open source and it is very easy to use. What more could you ask for?
| You must Sign In to use this message board. |
|
| | Msgs 1 to 16 of 16 (Total in Forum: 16) (Refresh) | FirstPrevNext |
|
 |
|
|
First,thanks to author for this tools. And,I have a question about collection.For example,I have a table named tblGallery.what can I do for get all records from this table. My codes: { TblGalleryCollection _tblGalleryCollection = new TblGalleryCollection(); IEnumerator ie=_tblGalleryCollection.GetEnumerator(); while (ie.MoveNext()==null) { ............... } return _tblGalleryCollection; }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
You could use LINQ to create a DAL but the whole purpose of this article was just to show people how to use SubSonic. Also remember that some people are still writing applications in .NET 2.0 or earlier which means LINQ is not available to them yet.
I did not say that this was the only way to create a DAL or that it is the best tool on the market. However, SubSonic is a very useful and FREE tool that will help you reduce your development time. The whole idea behind a product like this is to let you spend more time solving business problems and less time writing CRUD code.
|
| Sign In·View Thread·PermaLink | 3.67/5 (2 votes) |
|
|
|
 |
|
|
it looks like it does not create stored procedures but eventually uses inline sql, very, very bad

|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
Well if you create your own stored procedures then it will wrap the stored procedure calls for you. From what I have seen so far this product does nothing more than wrap what you already have in the database. If you are looking for something more advanced than you may want to take a look at NHibernate or LLBLGen.
|
| Sign In·View Thread·PermaLink | 4.67/5 (2 votes) |
|
|
|
 |
|
|
Yes, it sucks not having to write loads of pointless stored procedures that you can just generate.
|
| Sign In·View Thread·PermaLink | 1.33/5 (2 votes) |
|
|
|
 |
|
|
 |
|
|
Well there are different tools out there. This is just one of them. I am not trying to sell the tool to you. I am just another developer that decided to share some information with others on how to use SubSonic.
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
|
First of all, I don't believe in absolutes. Saying something is "bad" means you probably aren't very experienced in enterprise IT environments, where you have to cope with changing priorities all the time. I'm the manager of a software architecture, and we use all kinds of different techniques - every situation and every tool has its own pros and cons. We use SubSonic for simple data access, stored procedures, views etc. for more advanced stuff, and even some custom-made query builder classes.
Having said that, I'd like to comment that SubSonic has much more possibilities than this article describes. For example, it generates structs whith all table/view/column names as string fields, so you could write something like this, and it's impossible to make type errors:
Query q = new Query(Tables.Product) .WHERE(Product.Columns.ListPrice, Comparison.GreaterThan, 50.00) .ORDER_BY(Product.Columns.Title);
As for basic CRUD operations, the auto-generated classes work perfectly. Stored procedures are wrapped in a single class, so you can access them as well. The results from generated classes, the Query class, and stored procedures, can be returned as a reader or as a dataset.
The ultimate DAL does not exist, and SubSonic is far from perfect. But the fact that SubSonic doesn't need any pre-defined templates (you just supply a connection string and hit 'generate') makes it a very nice tool to generate and maintain a complete data model. Which you can extend with your own partial classes, by the way.
Cheers!
|
| Sign In·View Thread·PermaLink | 5.00/5 (2 votes) |
|
|
|
 |
|
|
Thank you so much for the support. You hit the nail on the head..."The ultimate DAL does not exist". But the fact of the matter is that a tool like SubSonic used under the correct circumstance can be a real time saver.
I did mention that part about partial classes and the wrapped stored procedures but I think most people make their conclusions about the product before they read the entire article. Thanks for pointing out the positives to all of the critics!
|
| Sign In·View Thread·PermaLink | 3.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
|
Thanks, did you ever do speed and load comparison for ".WHERE(Product.Columns.ListPrice, Comparison.GreaterThan, 50.00)" versus internal sql stored procedure code??
Also was sonic ever tested for security and sql injection attacks??
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Well I think sonic uses parameterized SQL behind the scenes but I have not officially verified that yet. You can probably get more details from the website - http://www.subsonicproject.com
A stored procedure would probably be faster because the execution plan is already compiled. However, you can still use stored procedures and use SubSonic just to wrap the execution of the SPROC.
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
Hi,
Of course stored procs are (generally) always faster than application-level querying (and that goes for any O/R mapping tool, of course). Stored procs are also faster than .NET's own ADO.NET classes, it's just a simple matter of overhead. But that's not the point - the point of products like SubSonic is that you trade in performance for maintainability. I will never, ever, want to maintain a list of 1000 basic CRUD stored procs - I'd rather add an extra server to the server farm instead. Those are everyday decisions in IT environments.
By the way, SubSonic's performance is not all that bad. We have some really busy backoffice applications using it and no-one's ever complained.
As for injection: basically, SubSonic does exactly the same as when you would create a SqlCommand manually and execute it (there's just an extra layer in between for multi-database-support). Injection is thus nearly impossible.
The included Query class parses and checks every string value you supply as a parameter value, no value ever gets injected directly in the final query. Actually, that level of security is sometimes annoying, for it does not allow any "sneaky" sql commands, and it is the reason we're using some custom SQL builder classes as well for certain scenarios (and then we have to check for injection risks ourselves, of course).
I'm not a SubSonic evangelist, by the way I have just used it intensively for the last few months, building a brand new software architecture with it, and therefore I've gotten pretty familiar with SS's pros and cons.
Cheers!
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
I'm curious what is so "bad" about inline sql:
- If the problem is perceived as performance, inline sql executes just as fast as stored procedures, and has done so since at least SQL Server 2000 (check Books Online). - If the problem is perceived as "SQL Injection", SubSonic DOES use inline SQL, but it ALSO uses PARAMETERIZED QUERIES, which makes it pretty much as SQL Injection-proof as a stored procedure call.
Much care has been taken by the developers to account for such perceived "shortcomings"...heck, the original author of the SubSonic library just got hired by Microsoft specifically related to his work on SubSonic...so even the 800lb Gorilla thinks the project has at least SOME merit 
- chris
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
General News Question Answer Joke Rant Admin
|