<?xml version="1.0" encoding="utf-8"?>
<feed xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom">
  <title>The .NET Universe revealed! - techniques for the .NET Developer</title>
  <link rel="alternate" type="text/html" href="http://blogs.mastronardi.be/Sandro/" />
  <link rel="self" href="http://blogs.mastronardi.be/Sandro/SyndicationService.asmx/GetAtom" />
  <icon>favicon.ico</icon>
  <updated>2011-04-05T23:01:44.5589518+02:00</updated>
  <author>
    <name>Sandro Mastronardi</name>
  </author>
  <subtitle>The secrets of .NET Development</subtitle>
  <id>http://blogs.mastronardi.be/Sandro/</id>
  <generator uri="http://dasblog.info/" version="2.3.12105.0">DasBlog</generator>
  <entry>
    <title>Patrick Tisseghem</title>
    <link rel="alternate" type="text/html" href="http://blogs.mastronardi.be/Sandro/2008/09/15/PatrickTisseghem.aspx" />
    <id>http://blogs.mastronardi.be/Sandro/PermaLink,guid,07f51d51-54ba-4d56-afa5-736d852b0fd7.aspx</id>
    <published>2008-09-15T23:49:07.155+02:00</published>
    <updated>2008-09-16T01:00:35.483125+02:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Normally I don't blog about non technical subjects.  But for a great guy I make
an exception.<br /><img height="95" alt="patrick.png" src="http://blogs.mastronardi.be/Sandro/content/binary/patrick.png" width="135" border="0" /></p>
        <p>
Last night while browsing the Tam Tam intranet I saw Mart Mullers post about
Patrick's death.  I was completely shocked...<br />
Even more because I, because of busy times at work, only came to read about his
death Yesterday
</p>
        <p>
Even though I'm currently not a SharePoint developer I had the chance of attending
a SharePoint course given by Patrick at Tam Tam.  Being a Belgian aswell it was
nice to have a fellow Belgian for the SharePoint training here (@ Tam Tam). 
Later on I met Patrick on the TechEd 2006 (Barcelona) where he invited me to
come along with the other Belgians and his colleagues to go out in Port Olympique. 
I will never forget this guesture of hospitality.  Since I was alone there (as
the only Belgian from Tam Tam in Barcelona at the National gathering) it was nice
to feel involved.  And this was just how he was, friendly, without counter-expectations. 
I remember him as a passionate person, and I will always remember and admire him for
all of this.<br />
Because of his deep impression he left me this struck me really hard last night, and
I have to admit that I shed some tears.  But no tears will ever wash away
his memory.  His knowledge will be alive in all SharePoint developers and this
way he will definitely never be forgotten.
</p>
        <p>
My condoleances go out to his family, friends and colleagues.  I hope you all
can find the strength to continue where he left off to make sure his legacy stays
alive.
</p>
        <p>
Patrick, I strongly believe that we'll meet again someday, and I'll buy you a beer
then, one of those (belgian beers) that you used in your courses....
</p>
        <img width="0" height="0" src="http://blogs.mastronardi.be/Sandro/aggbug.ashx?id=07f51d51-54ba-4d56-afa5-736d852b0fd7" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Custom XML Serializer based on reflection for serializing private variables</title>
    <link rel="alternate" type="text/html" href="http://blogs.mastronardi.be/Sandro/2007/08/22/CustomXMLSerializerBasedOnReflectionForSerializingPrivateVariables.aspx" />
    <id>http://blogs.mastronardi.be/Sandro/PermaLink,guid,7102bf54-51c9-4c47-af9e-bea8e656ff39.aspx</id>
    <published>2007-08-22T21:58:43.214+02:00</published>
    <updated>2008-02-12T11:52:30.56425+01:00</updated>
    <category term=".net" label=".net" scheme="http://blogs.mastronardi.be/Sandro/CategoryView,category,net.aspx" />
    <category term="Reflection" label="Reflection" scheme="http://blogs.mastronardi.be/Sandro/CategoryView,category,Reflection.aspx" />
    <category term="Xml" label="Xml" scheme="http://blogs.mastronardi.be/Sandro/CategoryView,category,Xml.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Have you too disliked the fact of having an object that, if you wanted to serialize
it, required to have all variables to be exposed via a gettable and settable public
property?  Well, I have!
</p>
        <p>
If I wanted to make an object with for example a read-only unique Id I had to expose
it with a setter to be able to serialize it back and forth.  This is really stupid
since you don't want objects that are saved to database to have a changable ID. 
Therefore it would be very usefull to serialize private variables instead of public
properties.  This way you can serialize a class without having to expose all
content to the developer using the class.
</p>
        <p>
For this reason I created a class that uses the undocumented IXmlSerializable interface. 
Microsoft claims this interface is for internal use only but it does this exact trick
like a charm.
</p>
        <p>
It has 3 important Methods that you have to implement:
</p>
        <ul>
          <li>
WriteXml(System.Xml.XmlWriter) 
</li>
          <li>
GetSchema() 
</li>
          <li>
ReadXml(System.Xml.XmlReader)</li>
        </ul>
        <p>
These methods do exactly what they say.  You implement the WriteXml method to
create your xml, and use the ReadXml method to read it back into a new object.
</p>
        <p>
the GetSchema() method is in case you want to validate your generated xml with a schema. 
I didn't use it because I used a flexible setup based on reflection.
</p>
        <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
              <p>
                <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">        <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
&lt;summary&gt;</span><br />
        <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
Converts the serializable members of an object into an XML document.</span><br />
        <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
&lt;/summary&gt;</span><br />
        <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
&lt;param name="writer"&gt;The XmlWriter used to write the XML-document instance.&lt;/param&gt;</span><br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> WriteXml(System.Xml.XmlWriter
writer) {<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">foreach</span>(FieldInfo
fi <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">in</span> GetFields()){<br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> nodeName <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> fi.Name.Trim('_');<br />
                writer.WriteStartElement(nodeName);<br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span>(fi.FieldType.BaseType
== <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">typeof</span>(System.ValueType)){<br />
                    writer.WriteString(fi.GetValue(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>).ToString());<br />
                }<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">else</span>{<br />
                    System.Text.StringBuilder
result <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> System.Text.StringBuilder();<br />
                    System.IO.StringWriter
sw <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> System.IO.StringWriter(
result );<br />
                    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">try</span> {<br />
                        System.Xml.Serialization.XmlSerializer
x <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> System.Xml.Serialization.XmlSerializer(
fi.FieldType );<br />
                        x.Serialize( <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> PrivateFieldXmlTextWriter(sw),
fi.GetValue(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>)
);<br />
                    }<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">catch</span>(Exception){<br />
                        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">throw</span>;<br />
                    }<br />
                    writer.WriteRaw(result.ToString());<br />
                }<br />
                writer.WriteEndElement(); <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
nodeName</span><br />
            }<br />
        }</span>
              </p>
              <p>
              </p>
            </span>
          </span>
        </span>
        <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
          <br />
 
</span>
        <p dir="ltr" style="MARGIN-RIGHT: 0px">
here I iterate trough every private variable (in the FieldInfo class) and write a
node with the value to the XmlWriter.
</p>
        <p dir="ltr" style="MARGIN-RIGHT: 0px">
          <font color="#ffa500">Sidenotes:</font>
        </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <ul dir="ltr">
            <li>
              <div style="MARGIN-RIGHT: 0px">
                <font color="#ffa500" size="1">(The GetFields() method
is used to get the FieldInfo array from a static hashtable if it was requested before
for performance reasons or from the class itself by reflection)</font>
              </div>
            </li>
            <li>
              <div style="MARGIN-RIGHT: 0px">
                <font color="#ffa500" size="1">You can see that I do
something else for a field of a valuetype compared to a field of a referencetype. 
A valuetype can be written in the node itself.  A reference type, a normal class,
has to be serialized too.  So here you see the serialisation code for serializing
classes.  But there is one thing different with normal serialisation, that is
the use of the PrivateFieldXmlTextWriter.  Instead of using a normal TextWriter
I use my own that overrides the method to write out the xml version code (&lt;?xml
version="1.0"?&gt;).  This is because this should only be written out on the
beginning of the xml document.</font>
              </div>
            </li>
          </ul>
        </blockquote>
        <p>
I do exactly the same the other way around for reading back into a class.  the
class must have a public default constructor to be able to instantiate a new class
and then fill it afterwards.  In .NET 2.0 this constructor may also be internal
(if I'm right).
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">        <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
&lt;summary&gt;</span><br />
        <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
Converts an XML document into an object using the specified reader.</span><br />
        <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
&lt;/summary&gt;</span><br />
        <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
&lt;param name="reader"&gt;The &lt;see cref="T:System.Xml.XmlReader"/&gt; used to
read the XML document.&lt;/param&gt;</span><br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> ReadXml(System.Xml.XmlReader
reader) {<br />
            XmlDocument
doc <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> XmlDocument();<br />
            doc.LoadXml(reader.ReadOuterXml());<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">foreach</span>(FieldInfo
fi <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">in</span> GetFields()){<br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> nodePath <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"/"</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.GetType().Name <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"/"</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> fi.Name.Trim('_');<br />
                XmlNode
node <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> doc.SelectSingleNode(nodePath)
;<br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> val <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> node.InnerText;<br />
                fi.SetValue(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>,ConvertXmlToDatatype(fi.FieldType,val));<br />
            }<br />
        }</span>
        </p>
        <p>
What I do here is using XPath queries to get the content from the node and I
made a method to return the object as the correct datatype.  After that it is
inserted via reflection into the variable it came from.
</p>
        <p>
One thing you see al the time is the Trimming of the underscore of a variable. 
I do this so that you can make all your variables start with an underscore but still
having valid xml without an underscore as the first character in the XmlNode. 
This wil make a variable like _id to be converted in Xml as &lt;id&gt;1&lt;/id&gt;.
</p>
        <p>
I hope you find this class very usefull and that it will solve many of your Xml Serialization
problems.
</p>
        <p>
Good luck.
</p>
        <a href="http://blogs.mastronardi.be/Sandro/content/binary/PrivateFieldSerializer.zip">PrivateFieldSerializer.zip
(2.21 KB)</a>
        <img width="0" height="0" src="http://blogs.mastronardi.be/Sandro/aggbug.ashx?id=7102bf54-51c9-4c47-af9e-bea8e656ff39" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Reading from and Writing to the same file simultaneously</title>
    <link rel="alternate" type="text/html" href="http://blogs.mastronardi.be/Sandro/2007/05/09/ReadingFromAndWritingToTheSameFileSimultaneously.aspx" />
    <id>http://blogs.mastronardi.be/Sandro/PermaLink,guid,4ce6fc1e-5595-4681-87d9-36f6aa90d5f8.aspx</id>
    <published>2007-05-09T22:38:09.937+02:00</published>
    <updated>2007-05-11T08:45:20.503625+02:00</updated>
    <category term=".net" label=".net" scheme="http://blogs.mastronardi.be/Sandro/CategoryView,category,net.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Have you never wondered how you could stream into a file while reading from it in
a separate process or application.  I know I have.  And first I'll tell
you why.
</p>
        <p>
I'm making a CMS (Content Management System) of my own where I want my resources (files,
images, ...) to be stored in the database.  Imagine this database and the server
serving the website having a not so superfast connection, what happens if a user requests
a file, and only a few milliseconds later another one requests the same file. 
The first request is not completed yet, so the file could not have been cached to
disk yet.  What would the second request do?  Get another connection to
the SQL server and start another stream from the database slowing down the first request
even more.  What if the second request could just start reading from the bytes
that where already on the server, and while the new bytes are coming in just streaming
those to the client as they come in.
</p>
        <p>
In reality the connection between your SQL and webserver isn't really slow, but the
files can be big enough to pose the same issue (Wanting to read a file that has already
started streaming to the same server).  In reality you would not let the first
request handle the download itself, but just let it start a thread that would start
the download and then start reading from the file in the request thread.  And
the same counts for all consecutive requests to the same file.
</p>
        <p>
I've been trying out several ways to achieve this goal and I found that a normal FileStream
could do the job (partly).<br />
The FileStream can read a file that is being written to if you specify the FileShare
parameter of both the streams to FileShare.ReadWrite and FileAccess.ReadWrite<br />
Why ReadWrite? I have to admit that I don't know the answer to that, but the fact
is that the Reading stream also needs Write access in order to do the reading and
writing simultaneously.
</p>
        <p>
There is one drawback, if the file is not written to disk before the reading stream
catches up, the stream just thinks the file is complete and finishes.  I first
tried working out a Copy method that involved retrying, but that wasn't really usefull
for most applications where you want to pass your stream to other third party code
that doesn't know about your retrying.  Hence I made my own GrowingFileStream
class that has its own system of trying to read from the file untill a timeout is
exceeded.  It is made very easy to make differences between a filestream for
Reading or for Writing.  A boolean configures the default FileStream this way
that the stream will ony do exactly that what you require from it.  Because it
could give strange behaviour when you start writing to a stream that was meant for
reading a file that is incomplete.  The code throws an exception if you try to
do the opposite.  You may descide yourself if you want this functionality, but
I figured it would come out handy.
</p>
        <p>
Below you see the most important part of the code, the reading code.  The writing
code is not changed from the default FileStream's Write method.
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">override</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> Read(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">byte</span>[]
array, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> offset, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> count)
{<br />
            CheckForReading();<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> bytesRead <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">base</span>.Read(array,
offset, count);<br />
            DateTime begin <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> DateTime.Now;<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">while</span>(_realSize
&gt; 0 &amp;&amp; <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.Length
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> _realSize
&amp;&amp; bytesRead == 0) {<br />
                bytesRead <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">base</span>.Read(array,
offset, count);<br />
                TimeSpan
tp <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> DateTime.Now <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">-</span> begin;<br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span>(tp.TotalMilliseconds
&gt;= <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.ReadTimeout)
{<br />
                    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span>(_throwsException)
{<br />
                        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">throw</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> TimeoutException(ERROR_TIMEOUT_EXCEEDED);<br />
                    }<br />
                    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">break</span>;<br />
                }<br />
            }<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> bytesRead;<br />
        }</span>
        </p>
        <p>
As you can see the Read method will try to re-Read if no bytes where found, and
it will retry this untill the ReadTimeout exceeds.  The behaviour then can be
different, If you specified the ThrowsExceptionOnTimeout as false it just stops reading,
but if you leave it to True it will throw a TimeoutException by default.  The
other most important thing to do right is, like I said before, use the ReadWrite enum
parameters correctly.  But if you download my class then this is done correctly
because the GrowingFileStream class doesn't let you specify these parameters that
are required to be of a specific value for this purpose.
</p>
        <p>
Feel free to download and use my class found below, and if you like it (or don't)
let me know your thoughts in the comments.  Please leave the link to my blog
intact.  Just in case you want to find back this information after a few months
or if you pass it to someone else.  It's the only thing I ask :-)
</p>
        <a href="http://blogs.mastronardi.be/Sandro/content/binary/GrowingFileStream.zip">GrowingFileStream.zip
(2,19 KB)</a>
        <img width="0" height="0" src="http://blogs.mastronardi.be/Sandro/aggbug.ashx?id=4ce6fc1e-5595-4681-87d9-36f6aa90d5f8" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Simple object/class to database persisting technique based on reflection</title>
    <link rel="alternate" type="text/html" href="http://blogs.mastronardi.be/Sandro/2007/03/28/SimpleObjectclassToDatabasePersistingTechniqueBasedOnReflection.aspx" />
    <id>http://blogs.mastronardi.be/Sandro/PermaLink,guid,6dd9d05f-87d1-4dbe-b7ae-1d5a35b8f42b.aspx</id>
    <published>2007-03-28T23:07:08.444+02:00</published>
    <updated>2011-04-05T23:01:44.5589518+02:00</updated>
    <category term=".net" label=".net" scheme="http://blogs.mastronardi.be/Sandro/CategoryView,category,net.aspx" />
    <category term="OO" label="OO" scheme="http://blogs.mastronardi.be/Sandro/CategoryView,category,OO.aspx" />
    <category term="Reflection" label="Reflection" scheme="http://blogs.mastronardi.be/Sandro/CategoryView,category,Reflection.aspx" />
    <category term="SQL" label="SQL" scheme="http://blogs.mastronardi.be/Sandro/CategoryView,category,SQL.aspx" />
    <content type="xhtml">
      <div 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" />
      </div>
    </content>
  </entry>
  <entry>
    <title>From html colors to .NET colors and back</title>
    <link rel="alternate" type="text/html" href="http://blogs.mastronardi.be/Sandro/2007/01/16/FromHtmlColorsToNETColorsAndBack.aspx" />
    <id>http://blogs.mastronardi.be/Sandro/PermaLink,guid,078addb4-2fcd-4299-9a31-c69f4e92feca.aspx</id>
    <published>2007-01-16T11:22:05.036+01:00</published>
    <updated>2007-03-29T00:27:21.5535+02:00</updated>
    <category term=".net" label=".net" scheme="http://blogs.mastronardi.be/Sandro/CategoryView,category,net.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
While exploring the deeps of .NET I found this wonderful class....<br />
The System.Drawing.ColorTranslator class.<br />
If I'd only known earlier.... This class has a static method that converts a <font size="2">System.Drawing.Color
to the Html notation of that color,<br />
and another to convert it back.</font></p>
        <p>
          <font size="2">These methods are respectively:<br /></font>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
              <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> colorHtml <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> System.Drawing.ColorTranslator.ToHtml(Color.LightBlue);<br />
System.Drawing.Color netColor <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> System.Drawing.ColorTranslator.FromHtml(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"#F3E0F7"</span>);</span>
          </span>
          <font size="2">
          </font>
        </p>
        <p>
          <font size="2">As I've said before, If I'd only known earlier.... These nice secrets
of .NET can be very usefull....<br />
But you have to know about them. Otherwise you start making these kind of functions
yourself.
</font>
        </p>
        <img width="0" height="0" src="http://blogs.mastronardi.be/Sandro/aggbug.ashx?id=078addb4-2fcd-4299-9a31-c69f4e92feca" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Make the noscript tag xhtml valid</title>
    <link rel="alternate" type="text/html" href="http://blogs.mastronardi.be/Sandro/2007/01/10/MakeTheNoscriptTagXhtmlValid.aspx" />
    <id>http://blogs.mastronardi.be/Sandro/PermaLink,guid,37fcb1bf-a541-45ef-b2ea-6027bb16b623.aspx</id>
    <published>2007-01-10T14:45:03.921+01:00</published>
    <updated>2008-02-12T11:50:50.8455+01:00</updated>
    <category term="Html" label="Html" scheme="http://blogs.mastronardi.be/Sandro/CategoryView,category,Html.aspx" />
    <category term="W3C" label="W3C" scheme="http://blogs.mastronardi.be/Sandro/CategoryView,category,W3C.aspx" />
    <category term="Xhtml" label="Xhtml" scheme="http://blogs.mastronardi.be/Sandro/CategoryView,category,Xhtml.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
For many statistics and tracking applications all over the internet you need
to implement a code snippet containing a noscript tag with a hidden image to make
the logging still work if scripting is disabled.  This is done with the &lt;noscript&gt;
tag.
</p>
        <p>
But...
</p>
        <p>
In Xhtml 1.0 Strict the noscript tag is invalid for the validator if inside a HTML
block element (&lt;p&gt;,&lt;th&gt;,&lt;td&gt;,...).  As a followup to the previous
post to make .NET applications Xhtml valid this one is a small addon, but it doesn't
require .net, only HTML.
</p>
        <p>
To make a &lt;noscript&gt;...&lt;/noscript&gt; tag valid for the w3c validator you
should replace it with &lt;object&gt;&lt;noscript&gt;&lt;div&gt;...&lt;/div&gt;&lt;/noscript&gt;&lt;/object&gt;.<br />
This weird followup of tags makes it possible to make the page validate.  The
object tag makes the use of the &lt;noscript&gt; tag possible in other tags like the
&lt;p&gt; tag.<br />
As for most statistics scripts you need to implement, the &lt;noscript&gt; tag contains
one single &lt;img ..../&gt; tag.  That would generate another error in the validator
because there is no &lt;img/&gt; tag allowed inside a &lt;noscript&gt; tag. 
Therefore the div is placed inside the &lt;noscript&gt; tag to make even that little
invisible image validate.
</p>
        <p>
Wonderful that this works, it made my search worth the while.
</p>
        <p>
          <font size="1">Source: </font>
          <a href="http://docs.phpcms.de/index.php/En:Why_do_I_get_validation_errors_with_DTD_XHTML_1.0_and_MAIL2CRYPT%3F">
            <font size="1">phpCMS
Wiki</font>
          </a>
          <br />
        </p>
        <img width="0" height="0" src="http://blogs.mastronardi.be/Sandro/aggbug.ashx?id=37fcb1bf-a541-45ef-b2ea-6027bb16b623" />
      </div>
    </content>
  </entry>
  <entry>
    <title>How To make your websites in MCMS XHtml Strict 1.0 Valid</title>
    <link rel="alternate" type="text/html" href="http://blogs.mastronardi.be/Sandro/2006/12/21/HowToMakeYourWebsitesInMCMSXHtmlStrict10Valid.aspx" />
    <id>http://blogs.mastronardi.be/Sandro/PermaLink,guid,686c7403-4063-4ad4-864f-7980ca012f55.aspx</id>
    <published>2006-12-21T17:26:55.035+01:00</published>
    <updated>2010-03-30T14:59:31.85825+02:00</updated>
    <category term=".net" label=".net" scheme="http://blogs.mastronardi.be/Sandro/CategoryView,category,net.aspx" />
    <category term="MCMS" label="MCMS" scheme="http://blogs.mastronardi.be/Sandro/CategoryView,category,MCMS.aspx" />
    <category term="Reflection" label="Reflection" scheme="http://blogs.mastronardi.be/Sandro/CategoryView,category,Reflection.aspx" />
    <category term="W3C" label="W3C" scheme="http://blogs.mastronardi.be/Sandro/CategoryView,category,W3C.aspx" />
    <category term="Xhtml" label="Xhtml" scheme="http://blogs.mastronardi.be/Sandro/CategoryView,category,Xhtml.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <em>
            <strong>
              <font color="#ffa500">If you don't use MCMS, you can still use a big part
of this Christmas gift, so read on.</font>
            </strong>
          </em>
        </p>
        <p>
          <font color="#000000">Have you ever tried making Xhtml Valid website's with MCMS,
I think not many of you have.</font>
        </p>
        <p>
          <font color="#000000">I ran in to this too, but only after trying a part of the solution
for another reason. That reason was to fix the broken Action in the Html form.<br />
I found some solutions on the internet to fix this issue for Url Rewriting in pure
.Net (1.1) websites.<br /></font>
          <font color="#000000">(This one for example: <a href="http://www.liquid-internet.co.uk/content/dynamic/pages/series1article1.aspx">http://www.liquid-internet.co.uk/content/dynamic/pages/series1article1.aspx</a>)<br />
This article shows how to remove the name attribute and change the action path to
something else, like say... the MCMS 'nice' url.</font>
        </p>
        <p>
          <font color="#000000">Everything seemed to work just fine, untill.... I added the
console on the page which has to be in the form. There is a bug in the console code
that checks if the console is placed inside an HtmlForm. The check does a hard check
like this:</font>
        </p>
        <font color="#000000">
          <p>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
              <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span>(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">typeof</span>(System.Web.UI.HtmlControls.HtmlForm)
== formobject.GetType())</span>
          </p>
        </font>
        <p>
          <font color="#000000">Instead of</font>
        </p>
        <font color="#000000">
          <p>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
              <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span>(formobject <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">is</span> System.Web.UI.HtmlControls.HtmlForm)</span>
          </p>
        </font>
        <p>
          <font color="#000000">This makes inheriting the HtmlForm control impossible when using
MCMS. But, luckily, there is a solution called reflection, which is also used on the
code from the other article.<br />
With Reflection it was possible to override the OnInit method and still fill all private
variables and call all private methods. I had already abandoned this Idea in the initial
project beause it was taking too long for the purpose. But around eight months later
there appeared a problem. The dutch government requests that their websites are now
XHTML1.0 Strict. This was not possible since the HtmlForm could not be overridden.
Since we work alot for the government we had to find a solution to that problem....
which I had almost solved when I could write to private variables (couldn't find how
to do that because it uses FieldInfo class where I expected something with 'Variable'
in the name. But eight months later there was something more in google about reflection
and private variables so this time I founc which class to use and I could finish the
job.</font>
        </p>
        <p>
          <font color="#000000">At that point I had full control over what was possible with
the HtmlForm and the Console for MCMS. I've overridden them both and changed them
extensively to make the scripts that are rendered Xhtml valid without breaking the
old functionality.</font>
        </p>
        <p>
          <font color="#000000">Another great feature that came with this endless possibilities
was that I could determine myself where to put the viewstate. Maybe you know, maybe
you don't but when google harvests your webpage it only reads the first few kilobytes
of your website. If your website has a large viewstate (which you should prevent anyway)
then you can choose to place it on the bottom of the form instead of the Top (the
default). You should be careful though, because if your application depends extensively
on viewstate and the page is not completely loaded your application might break because
viewstate is not fully loaded yet.</font>
        </p>
        <p>
          <font color="#000000">To do all this functionality I had to override and re-implement
lots of code from Microsoft. I used the <a href="http://www.aisto.com/roeder/dotnet/">.NET
Reflector</a> to get to the original code. Luckily this is possible because we would
have had a big problem and we would definitely loose the government as a customer.</font>
        </p>
        <p>
          <font color="#000000">I haven't placed many code here because the code sample wil
be self explanatory with the comments.</font>
        </p>
        <p>
          <font color="#000000">All I can say now is, good luck with developing all your other
code Xhtml Valid. Because it can be done!
</font>
        </p>
        <p>
          <font color="#000000">Sandro
</font>
        </p>
        <p>
          <a href="http://blogs.mastronardi.be/Sandro/content/binary/XhtmlValidForm.zip">XhtmlValidForm.zip
(10.11 KB)</a>
        </p>
        <p>
          <font size="1">Edit: I found a link that shows that someone else has stumbled on this
too, but unfortunately there was no solution for him at that time: </font>
          <a href="http://www.webservertalk.com/message535195.html">
            <font size="1">http://www.webservertalk.com/message535195.html</font>
          </a>
        </p>
        <img width="0" height="0" src="http://blogs.mastronardi.be/Sandro/aggbug.ashx?id=686c7403-4063-4ad4-864f-7980ca012f55" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Welcome to my weblog</title>
    <link rel="alternate" type="text/html" href="http://blogs.mastronardi.be/Sandro/2006/10/23/WelcomeToMyWeblog.aspx" />
    <id>http://blogs.mastronardi.be/Sandro/PermaLink,guid,c5a03ca4-3246-4912-a9e6-349bbdf8e024.aspx</id>
    <published>2006-10-24T00:21:48.391+02:00</published>
    <updated>2010-03-30T15:00:12.373875+02:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Welcome,
</p>
        <p>
What more can I say, this is my first post as you can see, and it will be the first
in a series of publications about problems I solved, and things I "invented" while
trying to find a solution for a specific problem.
</p>
        <p>
Hold on, the first post will arrive very soon, It will be about my XHTML Strict 1.0
Valid .NET Html form for Microsoft Content Management Server 2002 (MCMS 2002)
</p>
        <p>
I hope to see you back many times in the future and I hope I can give something useful
to the blog-community.
</p>
        <p>
Sandro
</p>
        <img width="0" height="0" src="http://blogs.mastronardi.be/Sandro/aggbug.ashx?id=c5a03ca4-3246-4912-a9e6-349bbdf8e024" />
      </div>
    </content>
  </entry>
</feed>