<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Nathan Bridgewater &#187; SubSonic</title>
	<atom:link href="http://www.integratedwebsystems.com/category/dotnet/subsonic-dotnet/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.integratedwebsystems.com</link>
	<description>My Little .NET Sandbox</description>
	<lastBuildDate>Thu, 19 Jan 2012 20:37:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Setting up SubSonic3 Repository Mode with an Existing Database</title>
		<link>http://www.integratedwebsystems.com/2010/10/setting-up-subsonic3-repository-mode-with-an-existing-database/</link>
		<comments>http://www.integratedwebsystems.com/2010/10/setting-up-subsonic3-repository-mode-with-an-existing-database/#comments</comments>
		<pubDate>Wed, 06 Oct 2010 17:00:00 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[SubSonic]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[Repository]]></category>
		<category><![CDATA[T4]]></category>

		<guid isPermaLink="false">http://www.integratedwebsystems.com/?p=973</guid>
		<description><![CDATA[Using SubSonic 3 respository mode has been a breath of fresh air...]]></description>
			<content:encoded><![CDATA[<p>Using <a href="http://www.subsonicproject.com/">SubSonic 3</a> <a href="http://subsonicproject.com/docs/Using_SimpleRepository">respository mode</a> has been a breath of fresh air for some of my projects. You can use simple POCOs (plain old CLR objects) and easily use <a href="http://msdn.microsoft.com/en-us/library/aa973811.aspx">inversion of control</a> with your application. However, it can be a little confusing using repository mode with an existing database since SubSonic’s default schema naming may not conform to your database. By using SubSonic’s schema attributes, you can get your application up and running relatively easily; and if you have a ton of tables, I have a T4 template that generates basic domain classes against your database to get you started. </p>
<p> <span id="more-973"></span><br />
<h3>Conforming to Your Database</h3>
<p>So first off: naming. SubSonic3 repository assumes that all your tables are pascal-cased and pluralized. So if you use a vanilla domain class against your database, it will only work with tables matching that naming pattern. Be aware that these attributes help determine the <em>database </em>properties; not the .NET runtime behavior of your application.&#160; For example, a <em>StringLength </em>attribute will instruct SubSonic to setup a varchar column with a defined length, but your .NET runtime will still use a String type and will still accept values longer than the associated database column.&#160; Here are the attributes you can use to tailor your classes to your database. </p>
<p><em>SubSonic.SqlGeneration.Schema </em>including<em>:</em></p>
<ul>
<li>[SubSonicDefaultSetting] – set a default value </li>
<li>[SubSonicIgnore] – Ignore a property or field </li>
<li>[SubSonicLongString] – ntext or text field </li>
<li>[SubSonicNullString] – Nullable varchar or text </li>
<li>[SubSonicNumericPrecision] – decimal with specific precision </li>
<li>[SubSonicPrimaryKey] – override primary key (use for primary key properties not named “Id”) </li>
<li>[SubSonicStringLength] – varchar custom length (use when length is not 50) </li>
<li>[SubSonicTableNameOverride] – override table name mapping for class </li>
<li>[SubSonicToManyRelation] – for one to many foreign key property mappings </li>
<li>[SubSonicToOneRelation] – for one to one foreign key property mappings </li>
</ul>
<p>&#160;</p>
<p>For the most part, you will use the TableNameOverride attribute to make your classes work with their corresponding tables. However, at times you will need to use the PrimaryKey if you don’t use “ID” as your primary key. The rest are extremely handy as well especially when it comes to null strings, text fields, and properties you want to ignore completely from the SQL translation to your database. Here is a sample class from an existing application: </p>
<pre class="brush: csharp; gutter: false;">[SubSonicTableNameOverride(&quot;effect&quot;)]
public partial class Effect
{
    public int Id { get; set; }
    public int SiteId { get; set; }
    public int? EffectTypeId { get; set; }
    public bool ApplyDefault { get; set; }
    [SubSonicNullString]
    [SubSonicStringLength(100)]
    public string Name { get; set; }
    [SubSonicNullString]
    [SubSonicStringLength(500)]
    public string Description { get; set; }
}</pre>
<p>Here, I use Id for my primary key, so it is not necessary to add the <em>PrimaryKey </em>attribute.&#160; I did use a NullString operator for a couple fields here that don’t require values. On a side-note, one of the philosophies behind requiring the NullString attribute and not simply assuming all strings are nullable is that the authors believe it’s more useful to use empty strings in place of null values because it alleviates many other issues down the road.&#160; While I don’t disagree, I still tend to use nullable strings out of habit. You can read more about their conventions from the <a href="http://www.subsonicproject.com/docs/Conventions">SubSonic Tome</a></p>
<h3>Domain Class Generator</h3>
<p>To get up and running quick, I built a simple domain class generator with T4 that writes out basic structures from an existing database repository-mode-friendly format. To run it, copy the files: Settings.ttinclude, SqlServer.ttinclude (or db specific ttinclude), and this Entities_Intial.tt file into your project folder. (Don’t add them to your visual studio project just yet).&#160; Edit the Settings.ttinclude file and customize your namespace, connection string, and database name fields.&#160; </p>
<p>Then include the <em>Entities_Initial.tt</em> file to your project. When you include this file, it will automatically attempt to run with your settings. It should separate each class into its own file. It will also generate a file for the core Entities_Initial that you can safely delete.&#160; (NOTE: To re-run the generation after including it to your project, right-click the <em>Entities_Initial.tt</em> file and select “Run Custom Tool”).</p>
<p>Copy these files to another folder in your project to prevent them from being accidentally overwritten with another generation. Unlike the generated partial classes of ActiveRecord and LinqTemplates where you maintain a partial extension, you want to maintain these domain classes directly because they truly should stand alone from the framework you’re using.&#160; Managing them like this gives you direct control over the properties and attributes in your domain model.&#160; You should also be able to use these classes with other IOC frameworks like NHibernate. (Granted… To drop the SubSonic reference, you will need to drop all the attributes at the same time). </p>
<p>&#160;</p>
<p><strong>Entities_Intial.tt</strong></p>
<pre class="brush: csharp; gutter: false;">&lt;#@ template language=&quot;C#v3.5&quot; debug=&quot;True&quot; hostspecific=&quot;True&quot; #&gt;
&lt;#@ include file=&quot;SQLServer.ttinclude&quot; #&gt;
&lt;#
    var list = LoadTables();
    foreach (Table table in list)
    {
#&gt;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Linq.Expressions;
using System.Collections;
using System.ComponentModel;
using System.Data.Common;
using SubSonic.SqlGeneration.Schema;

namespace &lt;#=Namespace #&gt;
{
    [SubSonicTableNameOverride(&quot;&lt;#=table.Name#&gt;&quot;)]
    public partial class &lt;#=table.CleanName#&gt;
    {
&lt;#
        foreach(Column col in table.Columns)
        {
            if (col.IsPK &amp;&amp; col.CleanName.ToLower() != &quot;id&quot;)
            {
#&gt;        [SubSonicPrimaryKey]
&lt;#            }

            var nullableNonString = string.Empty;
            var nullableString = string.Empty;
            if (col.IsNullable &amp;&amp; col.SysType != &quot;string&quot;)
            {
                nullableNonString = &quot;?&quot;;
            }
            if (col.SysType == &quot;string&quot;){
                if (col.IsNullable)
                {
#&gt;        [SubSonicNullString]
&lt;#                }
                if (col.DataType == &quot;text&quot;)
                {
#&gt;        [SubSonicLongString]
&lt;#                }
                else
                {
#&gt;        [SubSonicStringLength(&lt;#=col.MaxLength#&gt;)]
&lt;#                }
            }
#&gt;        public &lt;#=col.SysType#&gt;&lt;#=nullableNonString#&gt; &lt;#=col.CleanName#&gt; { get; set; }
&lt;#
        }
#&gt;
    }
}
&lt;#    SaveOutput(table.CleanName + &quot;.cs&quot;);
    }
#&gt;
}</pre>
<p>You can download the original script and its references <a href="/resources/p973/SubSonic-T4-Helpers.zip">directly</a> or get the <a href="http://github.com/nathanb/iws-snippets/tree/master/SubSonic-T4-Helpers">latest version</a> from my <a href="http://github.com/nathanb/iws-snippets">snippets project on GitHub</a>. I used the base elements of the T4 scripts from the <a href="http://github.com/subsonic/SubSonic-3.0-Templates">SubSonic-Templates project</a> for this. Currently, they only support MySql, Sql Server, and Sqlite databases. </p>
<p>Enjoy! </p>
]]></content:encoded>
			<wfw:commentRss>http://www.integratedwebsystems.com/2010/10/setting-up-subsonic3-repository-mode-with-an-existing-database/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Playing with SQLite, SubSonic3 and Repository Mode</title>
		<link>http://www.integratedwebsystems.com/2009/11/playing-with-sqlite-subsonic3-and-repository-mode/</link>
		<comments>http://www.integratedwebsystems.com/2009/11/playing-with-sqlite-subsonic3-and-repository-mode/#comments</comments>
		<pubDate>Sun, 22 Nov 2009 03:58:35 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[SubSonic]]></category>
		<category><![CDATA[Repository]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[SubSonic3]]></category>

		<guid isPermaLink="false">http://www.integratedwebsystems.com/?p=402</guid>
		<description><![CDATA[Okay, lemme tell ya&#8230; I really, really like SubSonic right now.&#160; I&#8217;m...]]></description>
			<content:encoded><![CDATA[<p>Okay, lemme tell ya&hellip; I really, really like SubSonic right now.&nbsp; I&rsquo;m building a basic data integration application, and I wanted a simple way to store some basic tracking data locally. I didn&rsquo;t want to build it into a Sql Server or create a super complicated data layer, so I decided to give SubSonic3&rsquo;s Repository Mode with SQLite a try. SQLite gives me a simple, zero-config, file-based database solution for the app, and SubSonic provides a nice, clean way to push and pull data with it.</p>
<p>First of all, if you haven&rsquo;t seen Conery&rsquo;s <a href="http://subsonicproject.com/docs/Simple_Repo_5_Minute_Demo" target="_blank">five minute demo video</a> on repository mode, you should. It&rsquo;s very cool.&nbsp; Once you watch it, you&rsquo;ll get the basics of migration and understand the idea of building the object model first while using the database purely as a storage mechanism. In this case, I built my class, and I&rsquo;m letting Migration handle all the schema generation for me. It will also create a new database file if one doesn&rsquo;t already exist. That&rsquo;s the idea right?</p>
<p><span id="more-402"></span></p>
<h3>Setup Your Configuration File</h3>
<p>For starters, don&rsquo;t forget to <a href="http://sqlite.phxsoftware.com/" target="_blank">download and install the System.Data.SQLite library first</a>. I ran their Windows installer and it worked just fine. Then add a connection string to your config file. Be sure to set the ProviderName to &nbsp;<strong>System.Data.SQLite</strong>. SubSonic uses the 2.0 provider model to determine the types required for the data connection.</p>
<pre class="brush: xml; gutter: false; toolbar: false;">&lt;connectionStrings&gt;
    &lt;add name=&quot;TrackerConnectionString&quot; connectionString=&quot;Data Source=Tracker.db3;&quot; providerName=&quot;System.Data.SQLite&quot;/&gt;
&lt;/connectionStrings&gt;</pre>
<h3>Create Your Data Classes</h3>
<p>Create your storage classes. If you&rsquo;re new to ORM/data layers, remember that each class definition represents a row in the database. In this case, I want a table called DSTFileTrackers with three columns: ID, Filename, and Imported. These are simple classes (other than the subsonic string length attribute). They don&rsquo;t inherit from any other base class. A nice attribute not used here would be the [SubSonicIgnore] attribute. It will allow you to define other properties that you don&rsquo;t want to store to the database like for example, read only properties.</p>
<pre class="brush: csharp; gutter: false; toolbar: false;">public class DSTFileTracker
{
    public long ID { get; set; }

    [SubSonic.SqlGeneration.Schema.SubSonicStringLength(100)]
    public string Filename { get; set; }

    public bool Imported { get; set; }
}</pre>
<h3>Write Your Implementation</h3>
<p>Lately, I&rsquo;ve been playing a lot with ASP.NET MVC, I&rsquo;ve been creating repository classes for my data objects.&nbsp; They&rsquo;re simple subject-matter classes that just handle business/data operations for a set of objects. In this case, I created one called TrackerRepository and implemented most of my SubSonic code there. Later on, I could build an interface for the repository and then set it up for unit testing or make it adaptable to switch to another data layer.</p>
<p>So here&rsquo;s a sample calling code.</p>
<pre class="brush: csharp; gutter: false; toolbar: false;">var tracker = _Repo.DSTFiles.Where(o =&gt; o.Filename == file.name).FirstOrDefault();
if (tracker == null)
{
    tracker = new DSTFileTracker();
    tracker.Filename = file.name;
    _Repo.SaveDSTFileTracker(tracker);
}</pre>
<p>This save function below lives in my repository class. You can see how nice and clean these statements are. There&rsquo;s a ton of potential here. Repository mode can do a lot of really cool stuff like deleting many records at once by expression or doing partial inserts and updates.</p>
<pre class="brush: csharp; gutter: false; toolbar: false;">public void SaveDSTFileTracker(DSTFileTracker data)
{
    if (_Repo.Exists&lt;DSTFileTracker&gt;(o =&gt; o.ID == data.ID))
        _Repo.Update&lt;DSTFileTracker&gt;(data);
    else
        _Repo.Add&lt;DSTFileTracker&gt;(data);
}</pre>
<p>So all in all it was pretty easy to do. You&rsquo;ll notice I ran an existence check. The SimpleRepository doesn&rsquo;t have this built into a save function like ActiveRecord, but it&rsquo;s not a big deal to do manually.</p>
<h3>Catching SubSonic Gotchas</h3>
<p>This library is new and like all new libraries, you&rsquo;ll run into a bug here and there. Hopefully as more and more people use it, the SubSonic community will become more aware of the bugs out there and can fix them.&nbsp; I ran into a few myself just while doing this. These are mostly specific to the SQLite portion of SubSonic. They were all very easy to fix, and it&rsquo;s very easy to submit your own patches. Checkout their <a href="http://subsonicproject.com/docs/Submit_Patch" target="_blank">GitHub demo video here</a>.&nbsp; <strike>You can access my branch directly for the fixed code</strike>.<strike> I&#39;ve applied for a code pull, but it takes a few days and code review before they plug it into the main.</strike></p>
<h4>Update August 16th, 2010</h4>
<p>I&#39;ve recently beeing using SubSonic post 3.0.0.4 version with SQLite and MySql, and most of these issues have been resolved. I pulled down my version of the repository since it&#39;s very old. I highly recommened upgrading to the latest one, which should not require any code changes. Check out one of my more recent posts that discusses <a href="http://www.integratedwebsystems.com/2010/08/subsonic3-works-on-mono/">SubSonic and Mono</a></p>
<p>Here&rsquo;s a few of the issues I ran into:</p>
<ul>
<li><strike>SQLite&rsquo;s auto-incrementing integer can only be 64bit [integer] rather than 32bit [int]. SubSonic will go and create the 64bit field during migration though; you just won&rsquo;t see an error until you try to read it back. So if your ID property is an [int], change it to a [long].</strike></li>
<li><strike>The default code for [bool] creates a tinyint field in SQLite.&nbsp; I had to tweak the Subsonic code by changing it to use a bit.&nbsp; When reading the values, it breaks because tinyint == Byte and SubSonic sets values to data properties by casting them directly to their actual type in the reader.</strike></li>
<li><strike>When running an Update&lt;T&gt;, I get a NullReferenceException.&nbsp; This is a bug in SubSonic and already <a href="http://github.com/subsonic/SubSonic-3.0/issues/#issue/123" target="_blank">has an issue posted</a>. I submitted a patch for this.&nbsp; It&rsquo;s a simple column name mismatch in the update script generator.</strike></li>
<li>Just like in Linq to Sql when you do custom Lambda expressions with unrelated fields, it could cause problems. I was doing a funky Where(o=&gt;o.Equals(y)) which blew up my stuff because the LINQ predicate expression couldn&rsquo;t figure out how to parse Equals() and CompareTo() to SQLite syntax.&nbsp; So keep it simple. <img src='http://www.integratedwebsystems.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.integratedwebsystems.com/2009/11/playing-with-sqlite-subsonic3-and-repository-mode/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

