<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" version="2.0">
  <channel>
    <title>The .NET Universe revealed! - techniques for the .NET Developer - SQL</title>
    <link>http://blogs.mastronardi.be/Sandro/</link>
    <description>The secrets of .NET Development</description>
    <language>en-us</language>
    <copyright>Sandro Mastronardi</copyright>
    <lastBuildDate>Wed, 28 Mar 2007 21:07:08 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.12105.0</generator>
    <managingEditor>sandro.mastronardi@mastrosoft.com</managingEditor>
    <webMaster>sandro.mastronardi@mastrosoft.com</webMaster>
    <item>
      <trackback:ping>http://blogs.mastronardi.be/Sandro/Trackback.aspx?guid=6dd9d05f-87d1-4dbe-b7ae-1d5a35b8f42b</trackback:ping>
      <pingback:server>http://blogs.mastronardi.be/Sandro/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.mastronardi.be/Sandro/PermaLink,guid,6dd9d05f-87d1-4dbe-b7ae-1d5a35b8f42b.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://blogs.mastronardi.be/Sandro/CommentView,guid,6dd9d05f-87d1-4dbe-b7ae-1d5a35b8f42b.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.mastronardi.be/Sandro/SyndicationService.asmx/GetEntryCommentsRss?guid=6dd9d05f-87d1-4dbe-b7ae-1d5a35b8f42b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It is well known that there are many Database Persisting libraries out there on the
net.  But for some reason I don't like them too much... Why is that? because
they are very complex.  I like to have my objects lightweight and I like to be
able to see what happens in the back.
</p>
        <p>
The way I did this uptill now was by making a class with Properties of which the private
fields (variables) where initialized by a method (or constructor) that expects
an System.Data.IDataReader (for cross database compatability).<br />
I would create a method that would get a DataReader from sql and pass that on with
the constructor or with the method.  It would result in classes with code like
this:
</p>
        <p>
          <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px">        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;summary&gt;</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
Constructor to create object from database</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;/summary&gt;</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;param name="idr"&gt;&lt;/param&gt;</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">internal</span> Resource(IDataReader
idr) {<br />
            ParseDataReader(idr);<br />
        }<br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;summary&gt;</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
Parse the datareader with the data from the database</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;/summary&gt;</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;param name="idr"&gt;&lt;/param&gt;</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">internal</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">override</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">void</span> ParseDataReader(IDataReader
idr) {<br />
            _mime <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> idr[RESMIME]
!<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> DBNull.Value
? idr[RESMIME].ToString():<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">null</span>;<br />
            _extention <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> idr[RESEXTENTION]
!<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> DBNull.Value
? idr[RESEXTENTION].ToString():<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">null</span>;<br />
            _localResource <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> Convert.ToBoolean(idr[RESLOCALRESOURCE]);<br />
            _blobId <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> Convert.ToInt64(idr[RESBLOBID]);<br />
        }<br /><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;summary&gt;</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
Save a resource to the database</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;/summary&gt;</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;returns&gt;The &lt;see cref="IDataReader"/&gt; with the new results&lt;/returns&gt;</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">internal</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">static</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">void</span> Save()
{<br />
            SqlConnection
conn <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">null</span>;<br />
            SqlTransaction
trans <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">null</span>;<br />
            <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">try</span> {<br />
                conn <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> Data.Connection.Create();<br />
                conn.Open();<br />
                SqlCommand
command <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> SqlHelper.CreateCommand(conn,
Constants.StoredProcedures.SAVE_RESOURCE);<br />
                command.CommandTimeout <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">int</span>.MaxValue;<br />
                command.Parameters.Add(<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">new</span> SqlParameter(<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"@ID"</span>, <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">this</span>.IsInDatabase
? resource.ID.ToString():<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">null</span>));<br />
                command.Parameters.Add(<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">new</span> SqlParameter(<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"@Name"</span>, <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">this</span>.Filename));<br />
                command.Parameters.Add(<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">new</span> SqlParameter(<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"@Mime"</span>, <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">this</span>.Mime));<br />
                command.Parameters.Add(<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">new</span> SqlParameter(<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"@Description"</span>, <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">this</span>.Description));<br />
                command.Parameters.Add(<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">new</span> SqlParameter(<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"@ParentGuid"</span>, <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">this</span>.ParentGuid));<br />
                command.Parameters.Add(<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">new</span> SqlParameter(<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"@LocalResource"</span>, <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">this</span>.LocalResource));<br />
                command.Parameters.Add(<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">new</span> SqlParameter(<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"@Size"</span>, <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">this</span>.Size));<br />
                command.Parameters.Add(<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">new</span> SqlParameter(<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"@VersionMajor"</span>, <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">this</span>.VersionMajor));<br />
                command.Parameters.Add(<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">new</span> SqlParameter(<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"@VersionMinor"</span>, <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">this</span>.VersionMinor));<br />
                command.Parameters.Add(<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">new</span> SqlParameter(<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"@AddBytes"</span>, <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">this</span>.HasNewStream));<br />
                SqlParameter
paramBlobId <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">new</span> SqlParameter(<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"@BlobID"</span>,SqlDbType.BigInt);<br />
                paramBlobId.Direction <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> ParameterDirection.Output;<br />
                command.Parameters.Add(paramBlobId);<br />
                <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">using</span>(IDataReader
result <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> command.ExecuteReader(CommandBehavior.CloseConnection))
{<br />
                    <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">if</span>(result.Read())
{<br />
                        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">this</span>.ParseDataReader(result);<br />
                    }<br />
                }<br />
               
} <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">finally</span> {<br />
                <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">if</span>(conn
!<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">null</span> &amp;&amp;
conn.State == ConnectionState.Open) {<br />
                    conn.Close();<br />
                }<br /><br />
            }<br />
        }</span>
        </p>
        <p>
          <font color="#ffa500" size="1">(Don't try to use the code, it is just an example,
it will not do anything)</font>
        </p>
        <p>
As you can see this can be a very repetetive task to make all fields persist to the
database.  And you can imagine what you have to do to add or remove a column:
</p>
        <ul>
          <li>
Add/Remove The column 
</li>
          <li>
Modify the Save/Update Stored Procedure 
</li>
          <li>
Add/Remove the field from the class (and corresponding property) 
</li>
          <li>
Add/Remove the Sql Parameter from the Save Method 
</li>
          <li>
Add/Remove the code to read from the IDataReader</li>
        </ul>
        <p>
And, on top of that the class is still full of useless code.<br />
But... I was thinking, since all fields are just in my class, isn't there a way to
just 'say', hey you, go to the database.<br />
Well, there is.  Using Attributes I can give some properties to a field and tell
it what the column name is for that field (for reading) and what stored procedure
parameter should be used (for saving).
</p>
        <p>
That sounds cool, but maybe you want to see an example for real:
</p>
        <p>
          <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px">
            <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">using</span> System;<br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">using</span> System.Collections.Generic;<br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">using</span> System.Text;<br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">using</span> BusinessLayer.Attributes;<br /><br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">namespace</span> BusinessLayer
{<br />
    [BusinessLayer.Attributes.DatabasePersistable(<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"SaveProduct"</span>, <span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"GetProductById"</span>),
Serializable]<br />
    <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">public</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">class</span> Product
: PersistableDatabaseObject&lt;Product&gt;{<br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">private</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">const</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">int</span> VAT_MIN <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> 0;<br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">private</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">const</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">int</span> VAT_MAX <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> 50;<br /><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">private</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">const</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">string</span> INVALID_VAT_PERCENTAGE <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span><span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"You
supplied an invalid VAT Percentage, it must be between {0} and {1}"</span>;<br /><br />
        [PersistToDatabase(<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"idProduct"</span>, <span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"@ID"</span>),
Attributes.PrimaryKey]<br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">private</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">int</span> _id <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">int</span>.MinValue;<br />
        [PersistToDatabase(<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"pName"</span>,<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"@Name"</span>)]<br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">private</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">string</span> _name <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">null</span>;<br />
        [PersistToDatabase(<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"pPrice"</span>,<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"@Price"</span>)]<br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">private</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">decimal</span> _price <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> 0;<br />
        [PersistToDatabase(<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"pVatPercentage"</span>,<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"@VatPercentage"</span>)]<br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">private</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">decimal</span> _vatPercentage <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> 21;<br /><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;summary&gt;</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
The database id of this product</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;/summary&gt;</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">public</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">int</span> ID
{<br />
            get {<br />
                <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">return</span> _id;<br />
            }<br />
        }<br /><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;summary&gt;</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
The name of the product</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;/summary&gt;</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">public</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">string</span> Name
{<br />
            get {<br />
                <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">return</span> _name;<br />
            }<br />
            set {<br />
                _name <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> value;<br />
            }<br />
        }<br /><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;summary&gt;</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
The current price of the product</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;/summary&gt;</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">public</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">decimal</span> Price
{<br />
            get {<br />
                <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">return</span> _price;<br />
            }<br />
            set {<br />
                _price <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> value;<br />
            }<br />
        }<br /><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;summary&gt;</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
Return the BTW Percentage of this product</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;/summary&gt;</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">public</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">decimal</span> VatPercentage
{<br />
            get {<br />
                <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">return</span> _vatPercentage;<br />
            }<br />
            set {<br />
                <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">if</span>(value
&lt; VAT_MIN || value &gt; VAT_MAX) {<br />
                    <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">throw</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">new</span> NotSupportedException(<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">string</span>.Format(INVALID_VAT_PERCENTAGE,VAT_MIN,VAT_MAX));<br />
                }<br />
                _vatPercentage <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> value;<br />
            }<br />
        }<br /><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;summary&gt;</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
Returns the price including Value Added Taxes (BTW)</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;/summary&gt;</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">public</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">decimal</span> PriceIncludingVat
{<br />
            get {<br />
                <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">return</span> Math.Round(_price <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">*</span> (_vatPercentage <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">/</span> 100M <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">+</span> 1),2);<br />
            }<br />
        }<br />
    }<br />
}<br /></span>
        </p>
        <p>
This is the entire class, nothing more, nothing less.  But how about saving to
database? There is no Save method.  and there is no method to get it from the
database.  Those are in the generic base class:<br /><font color="#000000" face="Courier New">PersistableDatabaseObject&lt;Product&gt;</font><br />
That object iterates trough all (private) fields with the <font color="#000000" face="Courier New">PersistToDatabase</font> attribute. 
It then gets the parameter name or the column name depending on if you are saving
or getting from the database.<br />
The stored procedures to do so are assigned to the class itself with the <font color="#000000" face="Courier New">DatabasePersistable</font> attribute.<br />
By assigning a <font color="#000000" face="Courier New">PrimaryKey</font> attribute
to the primary key column field of your class the object can automatically get the
object from database By ID.  The base class thus offers 3 basic methods:
</p>
        <ul>
          <li>
Save (or update with primary key) 
</li>
          <li>
GetById (get by primary key) 
</li>
          <li>
Reload (get by primary key, and replace local values with fresh values) 
</li>
          <li>
IsInDatabase (check if primary key is larger then zero)</li>
        </ul>
        <p>
Now, it may be possible to get a product by for example its name:
</p>
        <p>
          <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px">        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">public</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">static</span> ProductGetByStructuredComment(<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">string </span>name)
{<br />
            <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">return</span> PersistableDatabaseObject&lt;Product&gt;.GetFromDatabase(<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"GetProductByName"</span>, <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">new</span> System.Data.SqlClient.SqlParameter(<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"@Name"</span>,
name));<br />
        }</span>
        </p>
        <p>
As you can see this is not much code to just make it possible to get an object by
something else than its primary key.<br />
But how can this class give back the object by its correct type?  That is why
I used Generics.  you have to provide the correct type manually when inheriting,
and when calling the GetFromDatabase method, as you can see I used <font color="#000000" face="Courier New">PersistableDatabaseObject&lt;Product&gt;</font> a
few times.  That is the only requirement to make it work correctly, otherwise
the incorrect type may come back.  You can make mistakes about this, and I haven't
tested the outcome of that yet, but be warned that you must always use the correct
type.
</p>
        <p>
Now this works nice for a normal class, but getting by name like this last example
is not a good example, since the name may not be unique, and my stored procedure will
probably give back more than one result except when using:<br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">SELECT</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">TOP</span> 1
* <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">FROM</span> Products <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">WHERE</span> Name
= <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">'@Name'</span></span><br />
But most likely you want to retrieve a collection from the database.  And even
that is possible, but that isn't so difficult at all.  You just want it to be
a collection of the correct type, the rest is already handled inside the Type Class
itself.
</p>
        <p>
You can have a generics collection like this:
</p>
        <p>
          <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px">PersistableDatabaseCollection&lt;OrderItem&gt;
orderItemList <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> PersistableDatabaseCollection&lt;OrderItem&gt;.GetFromDatabase(<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"GetOrderItemsByOrderId"</span>, <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">new</span> System.Data.SqlClient.SqlParameter(<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"@ID"</span>,
order.ID));</span>
        </p>
        <p>
or you can make an OrderItemsCollection that inherits from <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px">PersistableDatabaseCollection&lt;OrderItem&gt;<br /></span>Either way it offers these standard methods:
</p>
        <ul>
          <li>
SaveAll 
</li>
          <li>
GetFromDatabase</li>
        </ul>
        <p>
The SaveAll method just iterates trough all children and calls Save and the GetFromDatabase
just fills the collection with its children but this time from a Stored Procedure
that returns more than one result.
</p>
        <p>
This is all very nice and easy for now, but if you want to know what happens in the
back, hold on.
</p>
        <p>
In my example I use ADO.NET to read and write to the database, but it is
very easy to alter it and to make it use the <a href="http://www.codeplex.com/entlib">Enterprise
Library</a>, for example.  To do so it may be very usefull to read on.
</p>
        <p>
The key to solving this is using reflection.  With reflection it is possible
to iterate trough fields (variables) of a class and to read their attributes. 
It would go too deep to explain Reflection itself, but there is enough information
out there that explains reflection.  For now it is just important to know what
reflection does for us now.  I'll show you the code to fill the class with
its content:
</p>
        <p>
          <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px">        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;summary&gt;</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
read the &lt;see cref="IDataReader"/&gt; into the private variables</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;/summary&gt;</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;param name="idr"&gt;The datareader to start reading&lt;/param&gt;</span><br />
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">public</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">virtual</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">void</span> ReadDataReader(IDataReader
idr) {<br />
            FieldInfo[]
fields <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">this</span>.GetType().GetFields(BindingFlags.Instance|BindingFlags.NonPublic);<br />
            <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">foreach</span>(FieldInfo
field <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">in</span> fields)
{<br />
                Attribute[]
attrs <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> (Attribute[])field.GetCustomAttributes(<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">typeof</span>(Attributes.PersistToDatabase), <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">true</span>);<br />
                <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">if</span>(attrs.Length ==
1) {<br />
                    Attributes.PersistToDatabase
persistAttribute <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> (Attributes.PersistToDatabase)attrs[0];<br />
                    <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">if</span>(field.FieldType.BaseType
== <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">typeof</span>(Enum))
{<br />
                        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">if</span>(idr[persistAttribute.ColumnName]
!<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> DBNull.Value){<br />
                            <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">foreach</span>(<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">int</span> value <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">in</span> Enum.GetValues(field.FieldType)){<br />
                                <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">if</span>(value
== Convert.ToInt32(idr[persistAttribute.ColumnName].ToString()[0])){<br />
                                    field.SetValue(<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">this</span>,
value);<br />
                                }<br />
                            }<br />
                            <br />
                        }<br />
                    } <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">else</span> {<br />
                        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">if</span>(idr[persistAttribute.ColumnName]
== DBNull.Value) {<br />
                            field.SetValue(<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">this</span>, <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">null</span>);<br />
                        } <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">else</span> {<br />
                            field.SetValue(<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">this</span>,
idr[persistAttribute.ColumnName]);<br />
                        }<br />
                    }<br />
                }<br />
            }<br />
        }</span>
        </p>
        <p>
Above you see the code that does the Reading trick, I'l explain the parts in detail
below:
</p>
        <p>
          <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px">FieldInfo[]
fields <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">this</span>.GetType().GetFields(BindingFlags.Instance|BindingFlags.NonPublic);</span>
        </p>
        <p>
To get an array of all private (<font color="#000000" face="Courier New">BindingFlags.NonPublic</font>)
instance (<font face="Courier New">BindingFlags.Instance</font>) i use this method.<br />
The GetFields method is a method of the Type class, since I call this code from inside
an instance, I can just get <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">this</span><font color="#000000" face="Courier New">.GetType()</font>to
get the correct type.
</p>
        <p>
          <font face="Courier New">
            <font color="#000000">Attribute[] attrs </font>
            <font size="2">
              <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span>
              <font color="#000000"> (Attribute[])field.GetCustomAttributes(</font>
              <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">typeof</span>
              <font color="#000000">(Attributes.PersistToDatabase), </font>
              <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">true</span>
            </font>
          </font>
          <font face="Courier New">
            <font color="#000000">);<br />
                </font>
            <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">if</span>
            <font color="#000000">(attrs.Length ==
1) {</font>
          </font>
          <br />
For each field I want to get all its PersistToDatabase attributes, that can be done
by providing that type to the GetCustomAttributes method, after which I can just check
if the array that is returned has exactly one (if not you declared something wrong,
so it is ignored) attribute of the type, if so the code will fill the field with the
value that corresponds with the columnname from the database as shown below:
</p>
        <p style="MARGIN-RIGHT: 0px" dir="ltr">
          <font face="Courier New">
            <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">
              <font size="2">      if</font>
            </span>
          </font>
          <font face="Courier New">
            <font color="#000000">(idr[persistAttribute.ColumnName]
== DBNull.Value) {<br />
         field.SetValue(</font>
            <font size="2">
              <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">this</span>
              <font color="#000000">, </font>
              <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">null</span>
            </font>
          </font>
          <font face="Courier New">
            <font color="#000000">);<br />
      } </font>
            <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">
              <font size="2">else</font>
            </span>
          </font>
          <font face="Courier New">
            <font color="#000000"> {<br />
         field.SetValue(</font>
            <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">
              <font size="2">this</font>
            </span>
          </font>
          <font color="#000000" face="Courier New">,
idr[persistAttribute.ColumnName]);<br />
      }</font>
        </p>
        <p>
It checks if the field is <font color="#000000" face="Courier New">DBNull.Value</font>,
and if so it sets the field to <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">null</span> ,
otherwise it sets it to the result (without casting, so the types must match)
</p>
        <p>
You may have noticed that there is a check to check if the object is of the type Enum,
this is done for a specific purpose where I wanted to have characters as the values
of my Enum, and I wanted them to be saed as characters to the database.  Hence
the enum is looped trough to get the correct value.
</p>
        <p>
I could now explain how the Save method works, but you can look at the source, and
I guess you will see what happens.... Every field is looped trough, and for each field
a SqlParameter is added with the Parametername from the attribute.  Then the
Stored Procedure for saving is called with those parameters.  Thus saving your
data to the database.  In the Save method you can also see my code for my 'character
enums'.<br />
In my code you can also see that I have a Generics dictionary to cache some reflection
information in static methods.  This is to make sure that Reflection doesn't
slow down the process.  And it is a Dictionary for the obvious reason that it
is located in the base class that must retain information for all classes that inherit
from it.
</p>
        <p>
Maybe you don't like the fact of still having to maintain stored procedures, and maybe
you prefer generating stored procedures, or not using them at all and let some system
create insert, update and select statements.  That choice can be entirely up
to you, but I prefer to be able to do everything myself, except for the things that
never change from an abstract point of view, and therefore I made this library. 
If you too like to remain in control of your communication with your sql server by
maintaining them yourself feel free to use this code since the 5 steps named
in the beginning of this article, are now reduced to 3 (of which only <strong>one</strong> requires
a <strong>change</strong> to your code <strong>in one</strong><strong>place</strong>)
and the first two actually really belong together (but they where also named separate
at the beginning of the article)
</p>
        <ul>
          <li>
Add/Remove column 
</li>
          <li>
Modify Stored procedure 
</li>
          <li>
Add field (and corresponding property)</li>
        </ul>
        <p>
I included the source of my base classes and attributes and a few of my real
classes as an example of how you can use it.  Hope you like it, please comment
on your experience with this code.  You can use this code in non commercial projects
for free, for use in commercial projects contact me.
</p>
        <p>
          <a href="http://blogs.mastronardi.be/Sandro/content/binary/DatbasePersistanceLibrary.zip">DatbasePersistanceLibrary.zip
(12,57 KB)</a>
        </p>
        <img width="0" height="0" src="http://blogs.mastronardi.be/Sandro/aggbug.ashx?id=6dd9d05f-87d1-4dbe-b7ae-1d5a35b8f42b" />
      </body>
      <title>Simple object/class to database persisting technique based on reflection</title>
      <guid isPermaLink="false">http://blogs.mastronardi.be/Sandro/PermaLink,guid,6dd9d05f-87d1-4dbe-b7ae-1d5a35b8f42b.aspx</guid>
      <link>http://blogs.mastronardi.be/Sandro/2007/03/28/SimpleObjectclassToDatabasePersistingTechniqueBasedOnReflection.aspx</link>
      <pubDate>Wed, 28 Mar 2007 21:07:08 GMT</pubDate>
      <description>&lt;p&gt;
It is well known that there are many Database Persisting libraries out there on the
net.&amp;nbsp; But for some reason I don't like them too much... Why is that? because
they are very complex.&amp;nbsp; I like to have my objects lightweight and I like to be
able to see what happens in the back.
&lt;/p&gt;
&lt;p&gt;
The way I did this uptill now was by making a class with Properties of which the private
fields (variables) where initialized by a method (or constructor)&amp;nbsp;that expects
an System.Data.IDataReader (for cross database compatability).&lt;br&gt;
I would create a method that would get a DataReader from sql and pass that on with
the constructor or with the method.&amp;nbsp; It would result in classes with code like
this:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
Constructor to create object from database&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;param name="idr"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;internal&lt;/span&gt; Resource(IDataReader
idr) {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ParseDataReader(idr);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
Parse the datareader with the data from the database&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;param name="idr"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;internal&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;override&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;void&lt;/span&gt; ParseDataReader(IDataReader
idr) {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_mime &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; idr[RESMIME]
!&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; DBNull.Value
? idr[RESMIME].ToString():&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;null&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_extention &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; idr[RESEXTENTION]
!&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; DBNull.Value
? idr[RESEXTENTION].ToString():&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;null&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_localResource &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; Convert.ToBoolean(idr[RESLOCALRESOURCE]);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_blobId &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; Convert.ToInt64(idr[RESBLOBID]);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
Save a resource to the database&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;returns&amp;gt;The &amp;lt;see cref="IDataReader"/&amp;gt; with the new results&amp;lt;/returns&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;internal&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;static&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;void&lt;/span&gt; Save()
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SqlConnection
conn &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;null&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SqlTransaction
trans &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;null&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;try&lt;/span&gt; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;conn &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; Data.Connection.Create();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;conn.Open();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SqlCommand
command &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; SqlHelper.CreateCommand(conn,
Constants.StoredProcedures.SAVE_RESOURCE);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;command.CommandTimeout &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;int&lt;/span&gt;.MaxValue;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;command.Parameters.Add(&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;new&lt;/span&gt; SqlParameter(&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"@ID"&lt;/span&gt;, &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;this&lt;/span&gt;.IsInDatabase
? resource.ID.ToString():&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;null&lt;/span&gt;));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;command.Parameters.Add(&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;new&lt;/span&gt; SqlParameter(&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"@Name"&lt;/span&gt;, &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;this&lt;/span&gt;.Filename));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;command.Parameters.Add(&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;new&lt;/span&gt; SqlParameter(&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"@Mime"&lt;/span&gt;, &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;this&lt;/span&gt;.Mime));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;command.Parameters.Add(&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;new&lt;/span&gt; SqlParameter(&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"@Description"&lt;/span&gt;, &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;this&lt;/span&gt;.Description));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;command.Parameters.Add(&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;new&lt;/span&gt; SqlParameter(&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"@ParentGuid"&lt;/span&gt;, &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;this&lt;/span&gt;.ParentGuid));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;command.Parameters.Add(&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;new&lt;/span&gt; SqlParameter(&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"@LocalResource"&lt;/span&gt;, &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;this&lt;/span&gt;.LocalResource));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;command.Parameters.Add(&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;new&lt;/span&gt; SqlParameter(&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"@Size"&lt;/span&gt;, &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;this&lt;/span&gt;.Size));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;command.Parameters.Add(&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;new&lt;/span&gt; SqlParameter(&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"@VersionMajor"&lt;/span&gt;, &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;this&lt;/span&gt;.VersionMajor));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;command.Parameters.Add(&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;new&lt;/span&gt; SqlParameter(&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"@VersionMinor"&lt;/span&gt;, &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;this&lt;/span&gt;.VersionMinor));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;command.Parameters.Add(&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;new&lt;/span&gt; SqlParameter(&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"@AddBytes"&lt;/span&gt;, &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;this&lt;/span&gt;.HasNewStream));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SqlParameter
paramBlobId &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;new&lt;/span&gt; SqlParameter(&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"@BlobID"&lt;/span&gt;,SqlDbType.BigInt);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;paramBlobId.Direction &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; ParameterDirection.Output;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;command.Parameters.Add(paramBlobId);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;using&lt;/span&gt;(IDataReader
result &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; command.ExecuteReader(CommandBehavior.CloseConnection))
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;if&lt;/span&gt;(result.Read())
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;this&lt;/span&gt;.ParseDataReader(result);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
} &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;finally&lt;/span&gt; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;if&lt;/span&gt;(conn
!&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;null&lt;/span&gt; &amp;amp;&amp;amp;
conn.State == ConnectionState.Open) {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;conn.Close();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font color=#ffa500 size=1&gt;(Don't try to use the code, it is just an example, it will
not do anything)&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
As you can see this can be a very repetetive task to make all fields persist to the
database.&amp;nbsp; And you can imagine what you have to do to add or remove a column:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Add/Remove The column 
&lt;li&gt;
Modify the Save/Update Stored Procedure 
&lt;li&gt;
Add/Remove the field from the class (and corresponding property) 
&lt;li&gt;
Add/Remove the Sql Parameter from the Save Method 
&lt;li&gt;
Add/Remove the code to read from the IDataReader&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
And, on top of that the class is still full of useless code.&lt;br&gt;
But... I was thinking, since all fields are just in my class, isn't there a way to
just 'say', hey you, go to the database.&lt;br&gt;
Well, there is.&amp;nbsp; Using Attributes I can give some properties to a field and tell
it what the column name is for that field (for reading)&amp;nbsp;and what stored procedure
parameter should be used (for saving).
&lt;/p&gt;
&lt;p&gt;
That sounds cool, but maybe you want to see an example for real:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"&gt;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;using&lt;/span&gt; System;&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;using&lt;/span&gt; System.Text;&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;using&lt;/span&gt; BusinessLayer.Attributes;&lt;br&gt;
&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;namespace&lt;/span&gt; BusinessLayer
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[BusinessLayer.Attributes.DatabasePersistable(&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"SaveProduct"&lt;/span&gt;, &lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"GetProductById"&lt;/span&gt;),
Serializable]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;public&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;class&lt;/span&gt; Product
: PersistableDatabaseObject&amp;lt;Product&amp;gt;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;private&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;const&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;int&lt;/span&gt; VAT_MIN &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; 0;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;private&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;const&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;int&lt;/span&gt; VAT_MAX &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; 50;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;private&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;const&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;string&lt;/span&gt; INVALID_VAT_PERCENTAGE &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"You
supplied an invalid VAT Percentage, it must be between {0} and {1}"&lt;/span&gt;;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[PersistToDatabase(&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"idProduct"&lt;/span&gt;, &lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"@ID"&lt;/span&gt;),
Attributes.PrimaryKey]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;private&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;int&lt;/span&gt; _id &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;int&lt;/span&gt;.MinValue;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[PersistToDatabase(&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"pName"&lt;/span&gt;,&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"@Name"&lt;/span&gt;)]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;private&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;string&lt;/span&gt; _name &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;null&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[PersistToDatabase(&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"pPrice"&lt;/span&gt;,&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"@Price"&lt;/span&gt;)]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;private&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;decimal&lt;/span&gt; _price &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; 0;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[PersistToDatabase(&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"pVatPercentage"&lt;/span&gt;,&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"@VatPercentage"&lt;/span&gt;)]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;private&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;decimal&lt;/span&gt; _vatPercentage &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; 21;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
The database id of this product&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;public&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;int&lt;/span&gt; ID
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;return&lt;/span&gt; _id;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
The name of the product&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;public&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;string&lt;/span&gt; Name
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;return&lt;/span&gt; _name;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_name &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; value;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
The current price of the product&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;public&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;decimal&lt;/span&gt; Price
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;return&lt;/span&gt; _price;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_price &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; value;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
Return the BTW Percentage of this product&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;public&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;decimal&lt;/span&gt; VatPercentage
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;return&lt;/span&gt; _vatPercentage;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;if&lt;/span&gt;(value
&amp;lt; VAT_MIN || value &amp;gt; VAT_MAX) {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;throw&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;new&lt;/span&gt; NotSupportedException(&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;string&lt;/span&gt;.Format(INVALID_VAT_PERCENTAGE,VAT_MIN,VAT_MAX));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_vatPercentage &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; value;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
Returns the price including Value Added Taxes (BTW)&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;public&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;decimal&lt;/span&gt; PriceIncludingVat
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;return&lt;/span&gt; Math.Round(_price &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;*&lt;/span&gt; (_vatPercentage &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;/&lt;/span&gt; 100M &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;+&lt;/span&gt; 1),2);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
This is the entire class, nothing more, nothing less.&amp;nbsp; But how about saving to
database? There is no Save method.&amp;nbsp; and there is no method to get it from the
database.&amp;nbsp; Those are in the generic base class:&lt;br&gt;
&lt;font color=#000000 face="Courier New"&gt;PersistableDatabaseObject&amp;lt;Product&amp;gt;&lt;/font&gt;
&lt;br&gt;
That object iterates trough all (private)&amp;nbsp;fields with the &lt;font color=#000000 face="Courier New"&gt;PersistToDatabase&lt;/font&gt;&amp;nbsp;attribute.&amp;nbsp;
It then gets the parameter name or the column name depending on if you are saving
or getting from the database.&lt;br&gt;
The stored procedures to do so are assigned to the class itself with the &lt;font color=#000000 face="Courier New"&gt;DatabasePersistable&lt;/font&gt;&amp;nbsp;attribute.&lt;br&gt;
By assigning a &lt;font color=#000000 face="Courier New"&gt;PrimaryKey&lt;/font&gt;&amp;nbsp;attribute
to the primary key column field of your class the object can automatically get the
object from database By ID.&amp;nbsp; The base class thus offers 3 basic methods:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Save (or update with primary key) 
&lt;li&gt;
GetById (get by primary key) 
&lt;li&gt;
Reload (get by primary key, and replace local values with fresh values) 
&lt;li&gt;
IsInDatabase (check if primary key is larger then zero)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Now, it may be possible to get a product by for example its name:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;public&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;static&lt;/span&gt; ProductGetByStructuredComment(&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;string &lt;/span&gt;name)
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;return&lt;/span&gt; PersistableDatabaseObject&amp;lt;Product&amp;gt;.GetFromDatabase(&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"GetProductByName"&lt;/span&gt;, &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;new&lt;/span&gt; System.Data.SqlClient.SqlParameter(&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"@Name"&lt;/span&gt;,
name));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
As you can see this is not much code to just make it possible to get an object by
something else than its primary key.&lt;br&gt;
But how can this class give back the object by its correct type?&amp;nbsp; That is why
I used Generics.&amp;nbsp; you have to provide the correct type manually when inheriting,
and when calling the GetFromDatabase method, as you can see I used &lt;font color=#000000 face="Courier New"&gt;PersistableDatabaseObject&amp;lt;Product&amp;gt;&lt;/font&gt;&amp;nbsp;a
few times.&amp;nbsp; That is the only requirement to make it work correctly, otherwise
the incorrect type may come back.&amp;nbsp; You can make mistakes about this, and I haven't
tested the outcome of that yet, but be warned that you must always use the correct
type.
&lt;/p&gt;
&lt;p&gt;
Now this works nice for a normal class, but getting by name like this last example
is not a good example, since the name may not be unique, and my stored procedure will
probably give back more than one result except when using:&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"&gt;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;SELECT&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;TOP&lt;/span&gt; 1
* &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;FROM&lt;/span&gt; Products &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;WHERE&lt;/span&gt; Name
= &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;'@Name'&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
But most likely you want to retrieve a collection from the database.&amp;nbsp; And even
that is possible, but that isn't so difficult at all.&amp;nbsp; You just want it to be
a collection of the correct type, the rest is already handled inside the Type Class
itself.
&lt;/p&gt;
&lt;p&gt;
You can have a generics collection like this:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"&gt;PersistableDatabaseCollection&amp;lt;OrderItem&amp;gt;
orderItemList &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; PersistableDatabaseCollection&amp;lt;OrderItem&amp;gt;.GetFromDatabase(&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"GetOrderItemsByOrderId"&lt;/span&gt;, &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;new&lt;/span&gt; System.Data.SqlClient.SqlParameter(&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"@ID"&lt;/span&gt;,
order.ID));&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
or you can make an OrderItemsCollection that inherits from &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"&gt;PersistableDatabaseCollection&amp;lt;OrderItem&amp;gt;&lt;br&gt;
&lt;/span&gt;Either way it offers these standard methods:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
SaveAll 
&lt;li&gt;
GetFromDatabase&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The SaveAll method just iterates trough all children and calls Save and the GetFromDatabase
just fills the collection with its children but this time from a Stored Procedure
that returns more than one result.
&lt;/p&gt;
&lt;p&gt;
This is all very nice and easy for now, but if you want to know what happens in the
back, hold on.
&lt;/p&gt;
&lt;p&gt;
In my example I use&amp;nbsp;ADO.NET&amp;nbsp;to read and write to the database, but it is
very easy to alter it and to make it use the &lt;a href="http://www.codeplex.com/entlib"&gt;Enterprise
Library&lt;/a&gt;, for example.&amp;nbsp; To do so it may be very usefull to read on.
&lt;/p&gt;
&lt;p&gt;
The key to solving this is using reflection.&amp;nbsp; With reflection it is possible
to iterate trough fields (variables) of a class and to read&amp;nbsp;their attributes.&amp;nbsp;
It would go too deep to explain Reflection itself, but there is enough information
out there that explains reflection.&amp;nbsp; For now it is just important to know what
reflection does for us now.&amp;nbsp; I'll show you the code to&amp;nbsp;fill the class with
its content:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
read the &amp;lt;see cref="IDataReader"/&amp;gt; into the private variables&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;param name="idr"&amp;gt;The datareader to start reading&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;public&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;virtual&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;void&lt;/span&gt; ReadDataReader(IDataReader
idr) {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FieldInfo[]
fields &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;this&lt;/span&gt;.GetType().GetFields(BindingFlags.Instance|BindingFlags.NonPublic);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;foreach&lt;/span&gt;(FieldInfo
field &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;in&lt;/span&gt; fields)
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Attribute[]
attrs &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; (Attribute[])field.GetCustomAttributes(&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;typeof&lt;/span&gt;(Attributes.PersistToDatabase), &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;true&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;if&lt;/span&gt;(attrs.Length&amp;nbsp;==
1) {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Attributes.PersistToDatabase
persistAttribute &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; (Attributes.PersistToDatabase)attrs[0];&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;if&lt;/span&gt;(field.FieldType.BaseType
== &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;typeof&lt;/span&gt;(Enum))
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;if&lt;/span&gt;(idr[persistAttribute.ColumnName]
!&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; DBNull.Value){&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;foreach&lt;/span&gt;(&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;int&lt;/span&gt; value &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;in&lt;/span&gt; Enum.GetValues(field.FieldType)){&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;if&lt;/span&gt;(value
== Convert.ToInt32(idr[persistAttribute.ColumnName].ToString()[0])){&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;field.SetValue(&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;this&lt;/span&gt;,
value);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;else&lt;/span&gt; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;if&lt;/span&gt;(idr[persistAttribute.ColumnName]
== DBNull.Value) {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;field.SetValue(&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;this&lt;/span&gt;, &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;null&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;else&lt;/span&gt; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;field.SetValue(&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;this&lt;/span&gt;,
idr[persistAttribute.ColumnName]);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Above you see the code that does the Reading trick, I'l explain the parts in detail
below:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"&gt;FieldInfo[]
fields &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;this&lt;/span&gt;.GetType().GetFields(BindingFlags.Instance|BindingFlags.NonPublic);&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
To get an array of all private&amp;nbsp;(&lt;font color=#000000 face="Courier New"&gt;BindingFlags.NonPublic&lt;/font&gt;)
instance (&lt;font face="Courier New"&gt;BindingFlags.Instance&lt;/font&gt;) i use this method.&lt;br&gt;
The GetFields method is a method of the Type class, since I call this code from inside
an instance, I can just get &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;this&lt;/span&gt;&lt;font color=#000000 face="Courier New"&gt;.GetType()&lt;/font&gt;to
get the correct type.
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&lt;font color=#000000&gt;Attribute[] attrs &lt;/font&gt;&lt;font size=2&gt;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt;&lt;font color=#000000&gt; (Attribute[])field.GetCustomAttributes(&lt;/font&gt;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;typeof&lt;/span&gt;&lt;font color=#000000&gt;(Attributes.PersistToDatabase), &lt;/font&gt;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;true&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#000000&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;if&lt;/span&gt;&lt;font color=#000000&gt;(attrs.Length&amp;nbsp;==
1) {&lt;/font&gt;&lt;/font&gt;
&lt;br&gt;
For each field I want to get all its PersistToDatabase attributes, that can be done
by providing that type to the GetCustomAttributes method, after which I can just check
if the array that is returned has exactly one (if not you declared something wrong,
so it is ignored) attribute of the type, if so the code will fill the field with the
value that corresponds with the columnname from the database as shown below:
&lt;/p&gt;
&lt;p style="MARGIN-RIGHT: 0px" dir=ltr&gt;
&lt;font face="Courier New"&gt;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&lt;font size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#000000&gt;(idr[persistAttribute.ColumnName]
== DBNull.Value) {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;field.SetValue(&lt;/font&gt;&lt;font size=2&gt;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;this&lt;/span&gt;&lt;font color=#000000&gt;, &lt;/font&gt;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;null&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#000000&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;/font&gt;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&lt;font size=2&gt;else&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#000000&gt; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;field.SetValue(&lt;/font&gt;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&lt;font size=2&gt;this&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font color=#000000 face="Courier New"&gt;,
idr[persistAttribute.ColumnName]);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
It checks if the field is &lt;font color=#000000 face="Courier New"&gt;DBNull.Value&lt;/font&gt;,
and if so it sets the field to&amp;nbsp;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;null&lt;/span&gt; ,
otherwise it sets it to the result (without casting, so the types must match)
&lt;/p&gt;
&lt;p&gt;
You may have noticed that there is a check to check if the object is of the type Enum,
this is done for a specific purpose where I wanted to have characters as the values
of my Enum, and I wanted them to be saed as characters to the database.&amp;nbsp; Hence
the enum is looped trough to get the correct value.
&lt;/p&gt;
&lt;p&gt;
I could now explain how the Save method works, but you can look at the source, and
I guess you will see what happens.... Every field is looped trough, and for each field
a SqlParameter is added with the Parametername from the attribute.&amp;nbsp; Then the
Stored Procedure for saving is called with those parameters.&amp;nbsp; Thus saving your
data to the database.&amp;nbsp; In the Save method you can also see my code for my 'character
enums'.&lt;br&gt;
In my code you can also see that I have a Generics dictionary to cache some reflection
information in static methods.&amp;nbsp; This is to make sure that Reflection doesn't
slow down the process.&amp;nbsp; And it is a Dictionary for the obvious reason that it
is located in the base class that must retain information for all classes that inherit
from it.
&lt;/p&gt;
&lt;p&gt;
Maybe you don't like the fact of still having to maintain stored procedures, and maybe
you prefer generating stored procedures, or not using them at all and let some system
create insert, update and select statements.&amp;nbsp; That choice can be entirely up
to you, but I prefer to be able to do everything myself, except for the things that
never change from an abstract point of view, and therefore I made this library.&amp;nbsp;
If you too like to remain in control of your communication with your sql server by
maintaining them yourself feel free to use this code since the&amp;nbsp;5 steps named
in the beginning of this article, are now reduced to 3 (of which only&amp;nbsp;&lt;strong&gt;one&lt;/strong&gt; requires
a&amp;nbsp;&lt;strong&gt;change&lt;/strong&gt; to your code &lt;strong&gt;in&amp;nbsp;one&lt;/strong&gt; &lt;strong&gt;place&lt;/strong&gt;)
and the first two actually really belong together (but they where also named separate
at the beginning of the article)
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Add/Remove column 
&lt;li&gt;
Modify Stored procedure 
&lt;li&gt;
Add field (and corresponding property)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I included the source of my base classes and attributes&amp;nbsp;and a few of my real
classes as an example of how you can use it.&amp;nbsp; Hope you like it, please comment
on your experience with this code.&amp;nbsp; You can use this code in non commercial projects
for free, for use in commercial projects contact me.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.mastronardi.be/Sandro/content/binary/DatbasePersistanceLibrary.zip"&gt;DatbasePersistanceLibrary.zip
(12,57 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.mastronardi.be/Sandro/aggbug.ashx?id=6dd9d05f-87d1-4dbe-b7ae-1d5a35b8f42b" /&gt;</description>
      <comments>http://blogs.mastronardi.be/Sandro/CommentView,guid,6dd9d05f-87d1-4dbe-b7ae-1d5a35b8f42b.aspx</comments>
      <category>.net</category>
      <category>OO</category>
      <category>Reflection</category>
      <category>SQL</category>
    </item>
  </channel>
</rss>