<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" version="2.0">
  <channel>
    <title>Chris Tacke - OpenNETCF.ORM</title>
    <link>http://blog.opennetcf.com/ctacke/</link>
    <description>Bringing Managed Code to the Embedded World</description>
    <copyright>Chris Tacke</copyright>
    <lastBuildDate>Mon, 01 Oct 2012 21:36:12 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>ctacke@opennetcf.com</managingEditor>
    <webMaster>ctacke@opennetcf.com</webMaster>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=56ea4c4d-1eb9-4b1b-9e3d-cc46fdb8286c</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,56ea4c4d-1eb9-4b1b-9e3d-cc46fdb8286c.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
There’s no doubt in my mind that code libraries and frameworks are fantastic for saving
time and work, after all I want to spend time solving my business problem, not writing
infrastructure.  Nowhere is this more true than it is with <a href="http://en.wikipedia.org/wiki/Object-relational_mapping" target="_blank">Object-Relational
Mapping</a>, or ORM, libraries.  
</p>
        <p>
Broadly speaking, if you’re still writing application code that requires that you
also write SQL, you’re wasting your time.  Wasting time thinking about SQL syntax. 
Wasting time writing it.  Wasting time testing, debugging and maintaining it.
</p>
        <p>
I believe this so much, but was so dissatisfied with any existing ORM offering, that <a href="http://orm.codeplex.com/" target="_blank">I
wrote my own ORM</a>. It wasn’t a trivial task, but I have something that does exactly
what I need, on the platforms I need, and does it at a speed that I consider more
than acceptable.  Occasionally I hit a data storage requirement that ORMs, even
my own, aren’t so good at.  
</p>
        <p>
ORM usage is usually viewed as one of two approaches: code first or data first. 
With the code-first approach, a developer defines the storage entity classes and the
ORM generates a backing database from them.  With data first, the developer feeds
a database into the ORM or an ORM tool, and it then generates the entity classes for
you.  
</p>
        <p>
But this doesn’t cover all scenarios – which is something no ORM that I’m aware of
seems to acknowledge.  Consider the following use-case (and this is a real-world
use case that I had to design for, not some mental exercise).
</p>
        <p>
I have an application that allows users to define storage for data at run time in
a completely ad-hoc manner.  They get to choose what data items they want to
save, but even those data items are dynamically available so they are available only
at run time.
</p>
        <p>
So we need to store effectively a flat table of data with an unknown set of columns. 
The column names and data types are unknown until after the application is running
on the user’s machine.
</p>
        <p>
So the entities are neither data first nor code first.  I’ve not thought of a
catchy term for these types of scenarios, so for now I’ll just call it “user first”
since the user has the idea of what they want to store and we have to accommodate
that.  This is why I created support in the OpenNETCF ORM for the DynamicEntity.
</p>
        <p>
Let’s assume that the user decides they wanted to store a FirstName and LastName for
a person.  For convenience, we also want to to store a generated ID for the Person
entities that get stored.
</p>
        <p>
At run time, we generate some FieldAttributes that define the Person:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span> var
fieldList = <span style="color: #0000ff">new</span> List&lt;FieldAttribute&gt;();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span> fieldList.Add(<span style="color: #0000ff">new</span> FieldAttribute()</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span> FieldName
= <span style="color: #006080">"ID"</span>,</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum5"> 5:</span> IsPrimaryKey
= <span style="color: #0000ff">true</span>,</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum6"> 6:</span> DataType
= System.Data.DbType.Int32</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum7"> 7:</span> });</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum8"> 8:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum9"> 9:</span> fieldList.Add(<span style="color: #0000ff">new</span> FieldAttribute()</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum10"> 10:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum11"> 11:</span> FieldName
= <span style="color: #006080">"FirstName"</span>,</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum12"> 12:</span> DataType
= System.Data.DbType.String</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum13"> 13:</span> });</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum14"> 14:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum15"> 15:</span> fieldList.Add(<span style="color: #0000ff">new</span> FieldAttribute()</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum16"> 16:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum17"> 17:</span> FieldName
= <span style="color: #006080">"LastName"</span>,</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum18"> 18:</span> DataType
= System.Data.DbType.String,</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum19"> 19:</span> AllowsNulls
= <span style="color: #0000ff">false</span></pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum20"> 20:</span> });</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
And then we create and register a DynamicEntityDefinition with the DataStore:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span> var
definition = <span style="color: #0000ff">new</span> DynamicEntityDefinition(</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span>
              <span style="color: #006080">"Person"</span>, </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span> fieldList, </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span> KeyScheme.Identity);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum5"> 5:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum6"> 6:</span> store.RegisterDynamicEntity(definition);</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
Now, any time we want to store an entity instance, we simply create a DynamicEntity
and pass that to the Insert method, just like any other Entity instance, and the ORM
handles storage for us.
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span> var
entity = <span style="color: #0000ff">new</span> DynamicEntity(<span style="color: #006080">"Person"</span>);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span> entity.Fields[<span style="color: #006080">"FirstName"</span>]
= <span style="color: #006080">"John"</span>;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span> entity.Fields[<span style="color: #006080">"LastName"</span>]
= <span style="color: #006080">"Doe"</span>;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span> store.Insert(entity);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum5"> 5:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum6"> 6:</span> entity
= <span style="color: #0000ff">new</span> DynamicEntity(<span style="color: #006080">"Person"</span>);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum7"> 7:</span> entity.Fields[<span style="color: #006080">"FirstName"</span>]
= <span style="color: #006080">"Jim"</span>;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum8"> 8:</span> entity.Fields[<span style="color: #006080">"LastName"</span>]
= <span style="color: #006080">"Smith"</span>;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum9"> 9:</span> store.Insert(entity);</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
The rest of the CRUD operations are similar, we simply have to name the definition
type where appropriate.  FOr example, retrieving looks like this:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span> var
people = store.Select(<span style="color: #006080">"Person"</span>)</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
Updating like this:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span> var
person = people.First();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span> person.Fields[<span style="color: #006080">"FirstName"</span>]
= <span style="color: #006080">"Joe"</span>;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span> person.Fields[<span style="color: #006080">"LastName"</span>]
= <span style="color: #006080">"Satriani"</span>;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span> store.Update(person);</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
And Deleting like this
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span> store.Delete(<span style="color: #006080">"Person"</span>,
people.First().Fields[<span style="color: #006080">"ID"</span>]);</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
We’re no longer bound by the either-or box of traditional ORM thinking, and it leads
to offering users some really interesting and powerful capabilities that before were
relegated to only those who wanted to abandon an ORM and hand-roll the logic.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=56ea4c4d-1eb9-4b1b-9e3d-cc46fdb8286c" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>OpenNETCF ORM: Dynamic Entities</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,56ea4c4d-1eb9-4b1b-9e3d-cc46fdb8286c.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/10/01/OpenNETCFORMDynamicEntities.aspx</link>
      <pubDate>Mon, 01 Oct 2012 21:36:12 GMT</pubDate>
      <description>&lt;p&gt;
There’s no doubt in my mind that code libraries and frameworks are fantastic for saving
time and work, after all I want to spend time solving my business problem, not writing
infrastructure.&amp;#160; Nowhere is this more true than it is with &lt;a href="http://en.wikipedia.org/wiki/Object-relational_mapping" target="_blank"&gt;Object-Relational
Mapping&lt;/a&gt;, or ORM, libraries.&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
Broadly speaking, if you’re still writing application code that requires that you
also write SQL, you’re wasting your time.&amp;#160; Wasting time thinking about SQL syntax.&amp;#160;
Wasting time writing it.&amp;#160; Wasting time testing, debugging and maintaining it.
&lt;/p&gt;
&lt;p&gt;
I believe this so much, but was so dissatisfied with any existing ORM offering, that &lt;a href="http://orm.codeplex.com/" target="_blank"&gt;I
wrote my own ORM&lt;/a&gt;. It wasn’t a trivial task, but I have something that does exactly
what I need, on the platforms I need, and does it at a speed that I consider more
than acceptable.&amp;#160; Occasionally I hit a data storage requirement that ORMs, even
my own, aren’t so good at.&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
ORM usage is usually viewed as one of two approaches: code first or data first.&amp;#160;
With the code-first approach, a developer defines the storage entity classes and the
ORM generates a backing database from them.&amp;#160; With data first, the developer feeds
a database into the ORM or an ORM tool, and it then generates the entity classes for
you.&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
But this doesn’t cover all scenarios – which is something no ORM that I’m aware of
seems to acknowledge.&amp;#160; Consider the following use-case (and this is a real-world
use case that I had to design for, not some mental exercise).
&lt;/p&gt;
&lt;p&gt;
I have an application that allows users to define storage for data at run time in
a completely ad-hoc manner.&amp;#160; They get to choose what data items they want to
save, but even those data items are dynamically available so they are available only
at run time.
&lt;/p&gt;
&lt;p&gt;
So we need to store effectively a flat table of data with an unknown set of columns.&amp;#160;
The column names and data types are unknown until after the application is running
on the user’s machine.
&lt;/p&gt;
&lt;p&gt;
So the entities are neither data first nor code first.&amp;#160; I’ve not thought of a
catchy term for these types of scenarios, so for now I’ll just call it “user first”
since the user has the idea of what they want to store and we have to accommodate
that.&amp;#160; This is why I created support in the OpenNETCF ORM for the DynamicEntity.
&lt;/p&gt;
&lt;p&gt;
Let’s assume that the user decides they wanted to store a FirstName and LastName for
a person.&amp;#160; For convenience, we also want to to store a generated ID for the Person
entities that get stored.
&lt;/p&gt;
&lt;p&gt;
At run time, we generate some FieldAttributes that define the Person:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; var
fieldList = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;FieldAttribute&amp;gt;();&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; fieldList.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; FieldAttribute()&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; FieldName
= &lt;span style="color: #006080"&gt;&amp;quot;ID&amp;quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt; 5:&lt;/span&gt; IsPrimaryKey
= &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;,&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt; 6:&lt;/span&gt; DataType
= System.Data.DbType.Int32&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt; 7:&lt;/span&gt; });&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt; 8:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt; 9:&lt;/span&gt; fieldList.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; FieldAttribute()&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt; 10:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt; 11:&lt;/span&gt; FieldName
= &lt;span style="color: #006080"&gt;&amp;quot;FirstName&amp;quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt; 12:&lt;/span&gt; DataType
= System.Data.DbType.String&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt; 13:&lt;/span&gt; });&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt; 14:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum15"&gt; 15:&lt;/span&gt; fieldList.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; FieldAttribute()&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum16"&gt; 16:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum17"&gt; 17:&lt;/span&gt; FieldName
= &lt;span style="color: #006080"&gt;&amp;quot;LastName&amp;quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum18"&gt; 18:&lt;/span&gt; DataType
= System.Data.DbType.String,&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum19"&gt; 19:&lt;/span&gt; AllowsNulls
= &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum20"&gt; 20:&lt;/span&gt; });&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
And then we create and register a DynamicEntityDefinition with the DataStore:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; var
definition = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DynamicEntityDefinition(&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; &lt;span style="color: #006080"&gt;&amp;quot;Person&amp;quot;&lt;/span&gt;, &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; fieldList, &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; KeyScheme.Identity);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt; 5:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt; 6:&lt;/span&gt; store.RegisterDynamicEntity(definition);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Now, any time we want to store an entity instance, we simply create a DynamicEntity
and pass that to the Insert method, just like any other Entity instance, and the ORM
handles storage for us.
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; var
entity = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DynamicEntity(&lt;span style="color: #006080"&gt;&amp;quot;Person&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; entity.Fields[&lt;span style="color: #006080"&gt;&amp;quot;FirstName&amp;quot;&lt;/span&gt;]
= &lt;span style="color: #006080"&gt;&amp;quot;John&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; entity.Fields[&lt;span style="color: #006080"&gt;&amp;quot;LastName&amp;quot;&lt;/span&gt;]
= &lt;span style="color: #006080"&gt;&amp;quot;Doe&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; store.Insert(entity);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt; 5:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt; 6:&lt;/span&gt; entity
= &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DynamicEntity(&lt;span style="color: #006080"&gt;&amp;quot;Person&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt; 7:&lt;/span&gt; entity.Fields[&lt;span style="color: #006080"&gt;&amp;quot;FirstName&amp;quot;&lt;/span&gt;]
= &lt;span style="color: #006080"&gt;&amp;quot;Jim&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt; 8:&lt;/span&gt; entity.Fields[&lt;span style="color: #006080"&gt;&amp;quot;LastName&amp;quot;&lt;/span&gt;]
= &lt;span style="color: #006080"&gt;&amp;quot;Smith&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt; 9:&lt;/span&gt; store.Insert(entity);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
The rest of the CRUD operations are similar, we simply have to name the definition
type where appropriate.&amp;#160; FOr example, retrieving looks like this:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; var
people = store.Select(&lt;span style="color: #006080"&gt;&amp;quot;Person&amp;quot;&lt;/span&gt;)&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Updating like this:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; var
person = people.First();&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; person.Fields[&lt;span style="color: #006080"&gt;&amp;quot;FirstName&amp;quot;&lt;/span&gt;]
= &lt;span style="color: #006080"&gt;&amp;quot;Joe&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; person.Fields[&lt;span style="color: #006080"&gt;&amp;quot;LastName&amp;quot;&lt;/span&gt;]
= &lt;span style="color: #006080"&gt;&amp;quot;Satriani&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; store.Update(person);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
And Deleting like this
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; store.Delete(&lt;span style="color: #006080"&gt;&amp;quot;Person&amp;quot;&lt;/span&gt;,
people.First().Fields[&lt;span style="color: #006080"&gt;&amp;quot;ID&amp;quot;&lt;/span&gt;]);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
We’re no longer bound by the either-or box of traditional ORM thinking, and it leads
to offering users some really interesting and powerful capabilities that before were
relegated to only those who wanted to abandon an ORM and hand-roll the logic.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=56ea4c4d-1eb9-4b1b-9e3d-cc46fdb8286c" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.ORM</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=eae63c52-1fd4-4c04-95d3-ff43c80cf25d</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,eae63c52-1fd4-4c04-95d3-ff43c80cf25d.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’m (finally) trying to publish some better, more formal documentation for <a href="http://orm.codeplex.com" target="_blank">the
ORM</a>.  I just posted a simple example of how you can create a one-to-many
relationship between Entities and how you can get the ORM to fill in the references
when you do a Select call.  <a href="http://orm.codeplex.com/wikipage?title=Retrieving%20Data%20%28READ%29" target="_blank">Take
a look at the ORM documentation for more details</a>.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=eae63c52-1fd4-4c04-95d3-ff43c80cf25d" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>ORM: Inserting References</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,eae63c52-1fd4-4c04-95d3-ff43c80cf25d.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/09/07/ORMInsertingReferences.aspx</link>
      <pubDate>Fri, 07 Sep 2012 22:11:48 GMT</pubDate>
      <description>&lt;p&gt;
I’m (finally) trying to publish some better, more formal documentation for &lt;a href="http://orm.codeplex.com" target="_blank"&gt;the
ORM&lt;/a&gt;.&amp;#160; I just posted a simple example of how you can create a one-to-many
relationship between Entities and how you can get the ORM to fill in the references
when you do a Select call.&amp;#160; &lt;a href="http://orm.codeplex.com/wikipage?title=Retrieving%20Data%20%28READ%29" target="_blank"&gt;Take
a look at the ORM documentation for more details&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=eae63c52-1fd4-4c04-95d3-ff43c80cf25d" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.ORM</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=1f4dce28-41f3-4109-9b55-6a8b930f5faa</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,1f4dce28-41f3-4109-9b55-6a8b930f5faa.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’ve just checked in new code changes and rolled a full release for <a href="http://orm.codeplex.com/" target="_blank">the
OpenNETCF ORM</a>.  The latest code changes add transaction support.  This
new release adds a load of features since the last (the last was way back in February),
most notably full support for <a href="http://sqlite.org/" target="_blank">SQLite</a> on
all of the following platforms: Windows Desktop, Windows CE, Windows Phone and Mono
for Android.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=1f4dce28-41f3-4109-9b55-6a8b930f5faa" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>ORM: Transactions are now supported</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,1f4dce28-41f3-4109-9b55-6a8b930f5faa.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/08/29/ORMTransactionsAreNowSupported.aspx</link>
      <pubDate>Wed, 29 Aug 2012 17:12:37 GMT</pubDate>
      <description>&lt;p&gt;
I’ve just checked in new code changes and rolled a full release for &lt;a href="http://orm.codeplex.com/" target="_blank"&gt;the
OpenNETCF ORM&lt;/a&gt;.&amp;#160; The latest code changes add transaction support.&amp;#160; This
new release adds a load of features since the last (the last was way back in February),
most notably full support for &lt;a href="http://sqlite.org/" target="_blank"&gt;SQLite&lt;/a&gt; on
all of the following platforms: Windows Desktop, Windows CE, Windows Phone and Mono
for Android.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=1f4dce28-41f3-4109-9b55-6a8b930f5faa" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>.NET Compact Framework</category>
      <category>Desktop Development</category>
      <category>MonoDroid</category>
      <category>OpenNETCF</category>
      <category>OpenNETCF.ORM</category>
      <category>Windows Phone 7</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=83bf3273-b9e0-4ca0-9f13-168e8832ba25</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,83bf3273-b9e0-4ca0-9f13-168e8832ba25.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://orm.codeplex.com/" target="_blank">The OpenNETCF ORM</a> has supported
SQLite for a while now – ever since I needed an ORM for Android – but somehow I’d
overlooked addeing SQLite support for the Compact Framework.  That oversight
has been addressed and support is now in <a href="http://orm.codeplex.com/SourceControl/list/changesets" target="_blank">the
latest change set</a> (99274).  I’ve not yet rolled it into the Release as it
doesn’t support Dynamic Entities yet, but that’s on the way.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=83bf3273-b9e0-4ca0-9f13-168e8832ba25" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>ORM Update: SQLite for Compact Framework now supported</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,83bf3273-b9e0-4ca0-9f13-168e8832ba25.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/08/20/ORMUpdateSQLiteForCompactFrameworkNowSupported.aspx</link>
      <pubDate>Mon, 20 Aug 2012 17:07:50 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://orm.codeplex.com/" target="_blank"&gt;The OpenNETCF ORM&lt;/a&gt; has supported
SQLite for a while now – ever since I needed an ORM for Android – but somehow I’d
overlooked addeing SQLite support for the Compact Framework.&amp;#160; That oversight
has been addressed and support is now in &lt;a href="http://orm.codeplex.com/SourceControl/list/changesets" target="_blank"&gt;the
latest change set&lt;/a&gt; (99274).&amp;#160; I’ve not yet rolled it into the Release as it
doesn’t support Dynamic Entities yet, but that’s on the way.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=83bf3273-b9e0-4ca0-9f13-168e8832ba25" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.ORM</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=0374759a-7f55-4e78-a240-bd9175e02853</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,0374759a-7f55-4e78-a240-bd9175e02853.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The Data Collector feature in our <a href="http://www.solution-family.com">Solution
Family product line</a> is one of the oldest (if not the oldest) sections of code,
and as such it's in need of a refactor to improve how it works.  We've updated
just about everything else that uses data storage to use the <a href="http://orm.codeplex.com">OpenNETCF
ORM framework</a>, but Data Collectors have languished, largely because they are complex. 
The Data Collector lets a user create an ad-hoc data collection definition that
translates into a SQL Compact Table at run time.  The problem with migrating
to ORM is that the ORM requires compile-time definitions of all Entities.  At
least that was the problem until today.
</p>
        <p>
I just checked in a new change set that supports the concept of a DynamicEntity (along
with all of the old goodness that is ORM).  Now you can create and register a
DynamicEntityDefinition with your IDataStore at run time and it will generate a table
for you in the back end.  New overloads for all of the typical CRUD commands
(Select, Update, Insert, Delete) allow you to just ask for the DynamicEntity by name
and it returns an array of DynamicEntity instances that hold the field names
and data values.
</p>
        <p>
It's in a "beta" state right now, but there's a test method in the change set that
shows general usage of all CRUD operations.  Give it a spin, and if you find
any bad behavior, <a href="http://orm.codeplex.com/workitem/list/basic">report it
on Codeplex</a>.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=0374759a-7f55-4e78-a240-bd9175e02853" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>ORM Update: Dynamic Entities</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,0374759a-7f55-4e78-a240-bd9175e02853.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/07/24/ORMUpdateDynamicEntities.aspx</link>
      <pubDate>Tue, 24 Jul 2012 19:27:45 GMT</pubDate>
      <description>&lt;p&gt;
The Data Collector&amp;nbsp;feature in our &lt;a href="http://www.solution-family.com"&gt;Solution
Family product line&lt;/a&gt; is one of the oldest (if not the oldest) sections of code,
and as such it's in need of a refactor to improve how it works.&amp;nbsp; We've updated
just about everything else that uses data storage to use the &lt;a href="http://orm.codeplex.com"&gt;OpenNETCF
ORM framework&lt;/a&gt;, but Data Collectors have languished, largely because they are complex.&amp;nbsp;
The Data Collector lets a user create an ad-hoc data&amp;nbsp;collection definition&amp;nbsp;that
translates into a SQL Compact Table at run time.&amp;nbsp; The problem with migrating
to ORM is that the ORM requires compile-time definitions of all Entities.&amp;nbsp; At
least that was the problem until today.
&lt;/p&gt;
&lt;p&gt;
I just checked in a new change set that supports the concept of a DynamicEntity (along
with all of the old goodness that is ORM).&amp;nbsp; Now you can&amp;nbsp;create and register&amp;nbsp;a
DynamicEntityDefinition with your IDataStore at run time and it will generate a table
for you in the back end.&amp;nbsp; New overloads for all of the typical CRUD commands
(Select, Update, Insert, Delete) allow you to just ask for the DynamicEntity by name
and it returns an array of&amp;nbsp;DynamicEntity instances that hold the field names
and data values.
&lt;/p&gt;
&lt;p&gt;
It's in a "beta" state right now, but there's a test method in the change set that
shows general usage of all CRUD operations.&amp;nbsp; Give it a spin, and if you find
any bad behavior, &lt;a href="http://orm.codeplex.com/workitem/list/basic"&gt;report it
on Codeplex&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=0374759a-7f55-4e78-a240-bd9175e02853" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.ORM</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=f2795a1f-678a-4855-b16c-32f915a81c96</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,f2795a1f-678a-4855-b16c-32f915a81c96.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We recently needed the ability to do most-recently-updated data caching in <a href="http://www.solution-family.com/" target="_blank">our
Solution Family products</a>.  Since the products use the <a href="http://orm.codeplex.com" target="_blank">OpenNETCF
ORM Framework</a>, it only made sense to update the framework itself to include events
that fire whenever an Insert, Update or Delete occurs.  In fact I added Before
and After versions for each. While I was at it, I also added a full complement of
virtual On[Before|After][Insert|Update|Delete] methods to the DataStore base, allowing
DataStore implementers to hook into the process as well.  I’m thinking I’ll use
those at some point in the future to add some form of Trigger capabilities.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=f2795a1f-678a-4855-b16c-32f915a81c96" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>ORM Update: Added events</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,f2795a1f-678a-4855-b16c-32f915a81c96.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/05/16/ORMUpdateAddedEvents.aspx</link>
      <pubDate>Wed, 16 May 2012 17:14:53 GMT</pubDate>
      <description>&lt;p&gt;
We recently needed the ability to do most-recently-updated data caching in &lt;a href="http://www.solution-family.com/" target="_blank"&gt;our
Solution Family products&lt;/a&gt;.&amp;#160; Since the products use the &lt;a href="http://orm.codeplex.com" target="_blank"&gt;OpenNETCF
ORM Framework&lt;/a&gt;, it only made sense to update the framework itself to include events
that fire whenever an Insert, Update or Delete occurs.&amp;#160; In fact I added Before
and After versions for each. While I was at it, I also added a full complement of
virtual On[Before|After][Insert|Update|Delete] methods to the DataStore base, allowing
DataStore implementers to hook into the process as well.&amp;#160; I’m thinking I’ll use
those at some point in the future to add some form of Trigger capabilities.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=f2795a1f-678a-4855-b16c-32f915a81c96" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.ORM</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=c0035aef-67d9-4e5e-a0c7-268ecc44f355</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,c0035aef-67d9-4e5e-a0c7-268ecc44f355.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We've started doing work creating client applications for a few of our products to
run on Android and iOS devices.  Since I'm a huge fan of code re-use, I took
the time this week to port the <a href="http://orm.codeplex.com">OpenNETCF.ORM</a> over
to <a href="http://xamarin.com/monoforandroid">Xamarin's Mono for Android</a> using
a <a href="http://www.sqlite.org/">SQLite backing store</a> implementation. 
The biggest challenge was that SQLite doesn't support TableDirect not ResultSets,
so it took a bit of code to get running.  Still, it took only a day and a half
to get what I feel is pretty good support up and running.  I've not yet tested
it through all of the possible permutations of queries, etc, but basic, single-table
CRUD operations all test out fine.
</p>
        <p>
So now a single code base can work on the Windows Desktop, Windows CE and Android
(probably iOS and Windows Phone as well with very little work). If you're doing MonoDroid
work, give it a try.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=c0035aef-67d9-4e5e-a0c7-268ecc44f355" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>OpenNETCF.ORM Now supports Xamarin Mono for Android</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,c0035aef-67d9-4e5e-a0c7-268ecc44f355.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/02/16/OpenNETCFORMNowSupportsXamarinMonoForAndroid.aspx</link>
      <pubDate>Thu, 16 Feb 2012 21:48:39 GMT</pubDate>
      <description>&lt;p&gt;
We've started doing work creating client applications for a few of our products to
run on Android and iOS devices.&amp;nbsp; Since I'm a huge fan of code re-use, I took
the time this week to port the &lt;a href="http://orm.codeplex.com"&gt;OpenNETCF.ORM&lt;/a&gt;&amp;nbsp;over
to &lt;a href="http://xamarin.com/monoforandroid"&gt;Xamarin's&amp;nbsp;Mono for Android&lt;/a&gt; using
a &lt;a href="http://www.sqlite.org/"&gt;SQLite backing store&lt;/a&gt; implementation.&amp;nbsp;
The biggest challenge was that SQLite doesn't support TableDirect not ResultSets,
so it took a bit of code to get running.&amp;nbsp; Still, it took only a day and a half
to get what I feel is pretty good support up and running.&amp;nbsp; I've not yet tested
it through all of the possible permutations of queries, etc, but basic, single-table
CRUD operations all test out fine.
&lt;/p&gt;
&lt;p&gt;
So now a single code base can work on the Windows Desktop, Windows CE and Android
(probably iOS and Windows Phone as well with very little work). If you're doing MonoDroid
work, give it a try.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=c0035aef-67d9-4e5e-a0c7-268ecc44f355" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>.NET Compact Framework</category>
      <category>MonoTouch</category>
      <category>OpenNETCF</category>
      <category>OpenNETCF.ORM</category>
      <category>Mono for Android</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=8a41ba23-a3cc-4786-a672-f8d45c2f15be</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,8a41ba23-a3cc-4786-a672-f8d45c2f15be.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This post is part of my "Software Development" series. <a href="http://blog.opennetcf.com/ctacke/2011/11/01/SoftwareDevelopmentSeriesTOC.aspx">The
TOC for the entire series can be found here</a>.
</p>
        <hr />
        <p>
Let’s start this post with a couple questions.  What is an ORM and why would
you use one?  If you don’t know the answer to both of these questions, then this
post is for you.  If you do know the answers, feel free to skip to the next post
(after I’ve created it of course).
</p>
        <p>
First, let’s look at what an ORM is. And ORM is an object-relational mapping. 
According to Wikipedia, which we all know is the infallible and definitive resource
for all knowledge, and ORM is “a <a href="http://en.wikipedia.org/wiki/Computer_programming">programming</a> technique
for converting data between incompatible <a href="http://en.wikipedia.org/wiki/Type_system">type
systems</a> in <a href="http://en.wikipedia.org/wiki/Object-oriented">object-oriented</a> programming
languages.”  Ok, what the hell does that mean?  My definition is a little
less “scholarly.”  I’d say that
</p>
        <blockquote>
          <p>
An ORM is a way to abstract your data storage into simple class objects (POCOs if
you’d like) so that you don’t have to worry about all the crap involved in actually
writing data fields, rows, tables and the like.  As a developer, I want to deal
with a “Person” class.  I don’t want to think about SQL statements.  I don’t
want to have to worry about indexes or tables or even how my “Person” gets stored
to or read from disk.  I just want to say “Save this Person instance” and have
it done.  THAT is what an ORM is.  A framework that lets me concentrate
on solving my business problem instead of spending days writing bullshit, mind-numbing,
error-prone data access layer code.
</p>
        </blockquote>
        <p>
Why would we use an ORM?  I think I’ve been fairly upfront that I consider myself
to be a lazy developer.  No, I don’t mean that I take shortcuts or do shoddy
work, I mean that I hate doing things more than once.  I hate having to write
reams of code to solve problems that have already been solved.  I’ve been writing
applications that consume data for years, and as a consequence, I’ve been writing
data access code for years.  If you’re not using an ORM, you probably know down
in your soul that this type of work flat-out sucks.  Anything that simplifies
data access to me is a win.
</p>
        <p>
Of course there are other, more tangible benefits as well.  If you’re using an
ORM, it’s often possible to swap out data stores – so maybe you could write to SQL
Server then swap a line of two in configuration and write to MySQL or an XML file. 
It also allows you to mock things or create stubs to remove data access (really handy
when someone tells you that your data access is what’s slowing things down when you’re
pretty sure it’s not).
</p>
        <p>
I can see that some of you still need convincing.  That’s good – you shouldn’t
ever just take someone’s word for it that they know what they’re doing.  Ask
for proof.  Well let’s look at a case of my own code, why I built the <a href="http://orm.codeplex.com" target="_blank">OpenNETCF
ORM</a> and how I was recently reminded why it’s a good thing.
</p>
        <p>
A couple years ago I wrote an application for a time and attendance device (i.e. a
time clock) that, not surprisingly, stored data about employees, punches, schedules,
etc.  on the device.  It also has the option to store it on a server and
synchronize the data from clock to server, but that’s not core to our discussion today. 
The point is that we were storing a fair bit of data and this was a project I did
right before I create the ORM framework.  It was, in fact, the project that made
it clear to me that I needed to write an ORM.
</p>
        <p>
Just about a month ago the customer wanted to extend the application, adding a couple
features to the time clock that required updates to how the data was stored. 
It took me very little time to realize that the existing DAL code was crap. 
Crap that I architected and wrote.  Sure, it works.  They’ve shipped thousands
of these devices and I’ve heard no complaints and had no bug reports, so functionally
it’s fine and it does exactly what was required.  Nonetheless the code is crap
and here’s why.
</p>
        <p>
First, let’s look at a table class in the DAL, like an Employee (the fat that the
DAL knows about tables is the first indication there’s a problem):
</p>
        <pre class="csharp" name="code">internal class EmployeeTable : Table 
{ 
    public override string Name { get { return "Employees"; } }

    public override ColumnInfo KeyField 
    { 
        get  
        { 
            return new ColumnInfo { Name = "EmployeeID", DataType = SqlDbType.Int }; 
        } 
    }

    internal protected override ColumnInfo[] GetColumnInfo() 
    { 
        return new ColumnInfo[] 
        { 
            KeyField, 
            new ColumnInfo { Name = "BadgeNumber", DataType = SqlDbType.NVarChar, Size = 50 }, 
            new ColumnInfo { Name = "BasePay", DataType = SqlDbType.Money }, 
            new ColumnInfo { Name = "DateOfHire", DataType = SqlDbType.DateTime }, 
            new ColumnInfo { Name = "FirstName", DataType = SqlDbType.NVarChar, Size = 50 }, 
            new ColumnInfo { Name = "LastName", DataType = SqlDbType.NVarChar, Size = 50 }, 
            // ... lots more column definitions ... 
        }; 
    }

    public override Index[] GetIndexDefinitions() 
    { 
        return new Index[] 
        { 
            new Index 
            { 
                Name = "IDX_EMPLOYEES_EMPLOYEEID_GUID",  
                SQL = "CREATE INDEX IDX_EMPLOYEES_EMPLOYEEID_GUID ON Employees (EmployeeID, GUID DESC)" 
            }, 
        }; 
    } 
}
</pre>
        <p>
So every table for an entity derives from Table, which looks like this (shorted a
load for brevity in this post):
</p>
        <pre class="csharp" name="code">public abstract class Table : ITable 
{ 
    internal protected abstract ColumnInfo[] GetColumnInfo();

    public abstract string Name { get; } 
    public abstract ColumnInfo KeyField { get; }

    public virtual string GetCreateTableSql() 
    { 
        // default implementation - override for different versions 
        StringBuilder sb = new StringBuilder(); 
        sb.Append(string.Format("CREATE TABLE {0} (", Name));

        ColumnInfo[] infoset = GetColumnInfo(); 
        int i; 
        for (i = 0; i &lt; (infoset.Length - 1); i++) 
        { 
            sb.Append(string.Format("{0},", infoset[i].ToColumnDeclaration())); 
        }

        sb.Append(string.Format("{0}", infoset[i].ToColumnDeclaration())); 
        sb.Append(")");

        return sb.ToString(); 
    }

    public virtual Index[] GetIndexDefinitions() 
    { 
        return null; 
    }

    public virtual IDbCommand GetInsertCommand() 
    { 
        SqlCeCommand cmd = new SqlCeCommand(); 

        // long, manual generation of the SQL and then creating the command

        return cmd; 
    }

    public IDbCommand GetUpdateCommand() 
    { 
        SqlCeCommand cmd = new SqlCeCommand(); 

        // long, manual generation of the SQL and then creating the command 

        return cmd; 
    }

    public IDbCommand GetDeleteCommand() 
    { 
        SqlCeCommand cmd = new SqlCeCommand(); 

        // long, manual generation of the SQL and then creating the command 

        return cmd; 
    }


</pre>
        <p>
Sure, I get a few bonus points for using inheritance so that each table doesn’t have
to do all of this work, but it’s still a pain.  Adding a new Table required that
I understand all of this goo, create the ColumnInfo right, know what the index stuff
is, etc.  And what happens when I need to add a field to an existing table? 
It’s not so clear.
</p>
        <p>
Now how about consuming this from the app?  When the app needs to get an Employee 
you have code like this:
</p>
        <pre class="csharp" name="code">public IEmployee[] GetAllEmployees(IDbConnection connection) 
{ 
    List<IEMPLOYEE>
list = new List<IEMPLOYEE>
(); using (SqlCeCommand command = new SqlCeCommand()) { command.CommandText = EMPLOYEES_SELECT_SQL2;
command.Connection = connection as SqlCeConnection; using (var rs = command.ExecuteResultSet(ResultSetOptions.Scrollable
| ResultSetOptions.Insensitive)) { GetEmployeeFieldOrdinals(rs, false); while (rs.Read())
{ IEmployee employee = EntityService.CreateEmployee(); employee.BadgeNumber = rs.IsDBNull(m_employeeFieldOrdinals["BadgeNumber"])
? null : rs.GetString(m_employeeFieldOrdinals["BadgeNumber"]); employee.BasePay =
rs.IsDBNull(m_employeeFieldOrdinals["EmployeeNumber"]) ? 0 : rs.GetDecimal(m_employeeFieldOrdinals["BasePay"]);
employee.DateOfHire = rs.IsDBNull(m_employeeFieldOrdinals["DateOfHire"]) ? DateTime.MinValue
: rs.GetDateTime(m_employeeFieldOrdinals["DateOfHire"]); employee.EmployeeID = rs.GetInt32(m_employeeFieldOrdinals["EmployeeID"]);
employee.FirstName = rs.GetString(m_employeeFieldOrdinals["FirstName"]); employee.LastName
= rs.GetString(m_employeeFieldOrdinals["LastName"]); string middleInitialStr = !rs.IsDBNull(m_employeeFieldOrdinals["MiddleInitial"])
? rs.GetString(m_employeeFieldOrdinals["MiddleInitial"]) : String.Empty; employee.MiddleInitial
= String.IsNullOrEmpty(middleInitialStr) ? '\0' : middleInitialStr[0]; // on and on
for another 100 lines of code) list.Add(employee); } } } return list.ToArray(); } 
</IEMPLOYEE></IEMPLOYEE></pre>
        <p>
Nevermind the fact that this could be improved a little with GetFields – the big issues
here are that you have to hard-code the SQL to get the data, then you have to parse
the results and fill out the Employee entity instance.  You do this for every
table.  You change a table, you then have to go change the SQL and every method
that touches the table.  The process is error prone, time consuming and just
not fun.  It also makes me uneasy because the test surface area needs to be big. 
How do I ensure that all places that access the table were fixed?  Unit tests
help give me some comfort, but really it has to go through full integration testing
of all features (since Employees are used by just about every feature on the clock).
</p>
        <p>
Now what would the ORM do for me here?  Without going into too much detail on
exactly how to use the ORM (we’ll look at that in another blog entry), let’s just
look at what the ORM version of things would look like.
</p>
        <p>
We’d not have any “Table” crap.  No SQL.  No building Commands and no parsing
Resultsets.  We’d just define an Entity like this:
</p>
        <pre class="csharp" name="code">[Entity] 
internal class Employee 
{ 
    [Field(IsPrimaryKey = true)] 
    public int EmployeeID { get; set; }        
    [Field] 
    public DateTime DateOfHire { get; set; } 
    [Field] 
    public string FirstName { get; set; } 
    [Field] 
    public string LastName { get; set; }

    // etc. 
}
</pre>
        <p>
Note how much cleaner this is than the Table code I had previously.  Also note
that this one class replaces *both* the Table class and the Business Object class. 
So this is much shorter.
</p>
        <p>
What about all of that create table, insert, update and delete SQL and index garbage
I had to know about, write and maintain?  Well, it’s replaced with this:
</p>
        <pre class="csharp" name="code">m_store = new DataStore(databasePath);

if (!m_store.StoreExists) 
{ 
    m_store.CreateStore(); 
}

m_store.AddType&lt;Employee&gt;(); 

</pre>
        <p>
That’s it.  Adding another Entity simply requires adding just one more line of
code – a call to AddType for the new Entity type.  In fact the ORM can auto-detect
all Entity types in an assembly with a single call if you want.  So that’s another
big win.  The base class garbage gets shifted into a framework that’s already
tested.  Less code for me to write means more time to solve my real problems
and less chance for me to add bugs.
</p>
        <p>
What about the long, ugly, unmaintainable query though?  Well that’s where the
ORM really, really pays off.  Getting all Employees becomes stupid simple.
</p>
        <pre class="csharp" name="code">var allEmployees = m_store.Select&lt;Employee&gt;();  </pre>
        <p>
Yep, that’s it. There are overloads that let you do filtering.  There are other
methods that allow you to do paging.  Creates, updates and deletes are similarly
easy.  
</p>
        <p>
Why did I create my own instead of using one that already exists?  Simple – there
isn’t one for the Compact Framework.  I also find that, like many existing IoC
frameworks, they try to be everything to everyone and end up overly complex. 
Another benefit to the OpenNETCF ORM is that it is fully supported on both the Compact
and Full Frameworks, so I can use it in desktop and device projects and not have to
cloud my brain with knowing multiple frameworks.  I even have a partial port
to Windows Phone (it just needs a little time to work around my use of TableDirect
in the SQL Compact implementation).  
</p>
        <p>
Oh, and it’s fast.  Really fast.  Since my initial target was a device with
limited resources, I wrote the code for that environment.  The SQL Compact implementation
avoids using the query parser whenever possible because experience has taught me that
as soon as you write actual SQL, you’re going to pay an order of magnitude performance
penalty (yes, it really is that bad).  It uses TableDirect whenever possible. 
It caches type info so reflection use is kept to a bare minimum.  It caches common
commands so if SQL was necessary, it at least can reuse query plans.
</p>
        <p>
So that’s why I <a href="http://orm.codeplex.com">use an ORM</a>. Doing data access
in any other way has become insanity.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=8a41ba23-a3cc-4786-a672-f8d45c2f15be" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>Software Development: An Intro to ORMs</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,8a41ba23-a3cc-4786-a672-f8d45c2f15be.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/11/21/SoftwareDevelopmentAnIntroToORMs.aspx</link>
      <pubDate>Mon, 21 Nov 2011 17:08:06 GMT</pubDate>
      <description>&lt;p&gt;
This post is part of my "Software Development" series. &lt;a href="http://blog.opennetcf.com/ctacke/2011/11/01/SoftwareDevelopmentSeriesTOC.aspx"&gt;The
TOC for the entire series can be found here&lt;/a&gt;.
&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;
Let’s start this post with a couple questions.&amp;nbsp; What is an ORM and why would
you use one?&amp;nbsp; If you don’t know the answer to both of these questions, then this
post is for you.&amp;nbsp; If you do know the answers, feel free to skip to the next post
(after I’ve created it of course).
&lt;/p&gt;
&lt;p&gt;
First, let’s look at what an ORM is. And ORM is an object-relational mapping.&amp;nbsp;
According to Wikipedia, which we all know is the infallible and definitive resource
for all knowledge, and ORM is “a &lt;a href="http://en.wikipedia.org/wiki/Computer_programming"&gt;programming&lt;/a&gt; technique
for converting data between incompatible &lt;a href="http://en.wikipedia.org/wiki/Type_system"&gt;type
systems&lt;/a&gt; in &lt;a href="http://en.wikipedia.org/wiki/Object-oriented"&gt;object-oriented&lt;/a&gt; programming
languages.”&amp;nbsp; Ok, what the hell does that mean?&amp;nbsp; My definition is a little
less “scholarly.”&amp;nbsp; I’d say that
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
An ORM is a way to abstract your data storage into simple class objects (POCOs if
you’d like) so that you don’t have to worry about all the crap involved in actually
writing data fields, rows, tables and the like.&amp;nbsp; As a developer, I want to deal
with a “Person” class.&amp;nbsp; I don’t want to think about SQL statements.&amp;nbsp; I don’t
want to have to worry about indexes or tables or even how my “Person” gets stored
to or read from disk.&amp;nbsp; I just want to say “Save this Person instance” and have
it done.&amp;nbsp; THAT is what an ORM is.&amp;nbsp; A framework that lets me concentrate
on solving my business problem instead of spending days writing bullshit, mind-numbing,
error-prone data access layer code.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Why would we use an ORM?&amp;nbsp; I think I’ve been fairly upfront that I consider myself
to be a lazy developer.&amp;nbsp; No, I don’t mean that I take shortcuts or do shoddy
work, I mean that I hate doing things more than once.&amp;nbsp; I hate having to write
reams of code to solve problems that have already been solved.&amp;nbsp; I’ve been writing
applications that consume data for years, and as a consequence, I’ve been writing
data access code for years.&amp;nbsp; If you’re not using an ORM, you probably know down
in your soul that this type of work flat-out sucks.&amp;nbsp; Anything that simplifies
data access to me is a win.
&lt;/p&gt;
&lt;p&gt;
Of course there are other, more tangible benefits as well.&amp;nbsp; If you’re using an
ORM, it’s often possible to swap out data stores – so maybe you could write to SQL
Server then swap a line of two in configuration and write to MySQL or an XML file.&amp;nbsp;
It also allows you to mock things or create stubs to remove data access (really handy
when someone tells you that your data access is what’s slowing things down when you’re
pretty sure it’s not).
&lt;/p&gt;
&lt;p&gt;
I can see that some of you still need convincing.&amp;nbsp; That’s good – you shouldn’t
ever just take someone’s word for it that they know what they’re doing.&amp;nbsp; Ask
for proof.&amp;nbsp; Well let’s look at a case of my own code, why I built the &lt;a href="http://orm.codeplex.com" target=_blank&gt;OpenNETCF
ORM&lt;/a&gt; and how I was recently reminded why it’s a good thing.
&lt;/p&gt;
&lt;p&gt;
A couple years ago I wrote an application for a time and attendance device (i.e. a
time clock) that, not surprisingly, stored data about employees, punches, schedules,
etc.&amp;nbsp; on the device.&amp;nbsp; It also has the option to store it on a server and
synchronize the data from clock to server, but that’s not core to our discussion today.&amp;nbsp;
The point is that we were storing a fair bit of data and this was a project I did
right before I create the ORM framework.&amp;nbsp; It was, in fact, the project that made
it clear to me that I needed to write an ORM.
&lt;/p&gt;
&lt;p&gt;
Just about a month ago the customer wanted to extend the application, adding a couple
features to the time clock that required updates to how the data was stored.&amp;nbsp;
It took me very little time to realize that the existing DAL code was crap.&amp;nbsp;
Crap that I architected and wrote.&amp;nbsp; Sure, it works.&amp;nbsp; They’ve shipped thousands
of these devices and I’ve heard no complaints and had no bug reports, so functionally
it’s fine and it does exactly what was required.&amp;nbsp; Nonetheless the code is crap
and here’s why.
&lt;/p&gt;
&lt;p&gt;
First, let’s look at a table class in the DAL, like an Employee (the fat that the
DAL knows about tables is the first indication there’s a problem):
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;internal class EmployeeTable : Table 
{ 
    public override string Name { get { return "Employees"; } }

    public override ColumnInfo KeyField 
    { 
        get  
        { 
            return new ColumnInfo { Name = "EmployeeID", DataType = SqlDbType.Int }; 
        } 
    }

    internal protected override ColumnInfo[] GetColumnInfo() 
    { 
        return new ColumnInfo[] 
        { 
            KeyField, 
            new ColumnInfo { Name = "BadgeNumber", DataType = SqlDbType.NVarChar, Size = 50 }, 
            new ColumnInfo { Name = "BasePay", DataType = SqlDbType.Money }, 
            new ColumnInfo { Name = "DateOfHire", DataType = SqlDbType.DateTime }, 
            new ColumnInfo { Name = "FirstName", DataType = SqlDbType.NVarChar, Size = 50 }, 
            new ColumnInfo { Name = "LastName", DataType = SqlDbType.NVarChar, Size = 50 }, 
            // ... lots more column definitions ... 
        }; 
    }

    public override Index[] GetIndexDefinitions() 
    { 
        return new Index[] 
        { 
            new Index 
            { 
                Name = "IDX_EMPLOYEES_EMPLOYEEID_GUID",  
                SQL = "CREATE INDEX IDX_EMPLOYEES_EMPLOYEEID_GUID ON Employees (EmployeeID, GUID DESC)" 
            }, 
        }; 
    } 
}
&lt;/pre&gt;
&lt;p&gt;
So every table for an entity derives from Table, which looks like this (shorted a
load for brevity in this post):
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;public abstract class Table : ITable 
{ 
    internal protected abstract ColumnInfo[] GetColumnInfo();

    public abstract string Name { get; } 
    public abstract ColumnInfo KeyField { get; }

    public virtual string GetCreateTableSql() 
    { 
        // default implementation - override for different versions 
        StringBuilder sb = new StringBuilder(); 
        sb.Append(string.Format("CREATE TABLE {0} (", Name));

        ColumnInfo[] infoset = GetColumnInfo(); 
        int i; 
        for (i = 0; i &amp;lt; (infoset.Length - 1); i++) 
        { 
            sb.Append(string.Format("{0},", infoset[i].ToColumnDeclaration())); 
        }

        sb.Append(string.Format("{0}", infoset[i].ToColumnDeclaration())); 
        sb.Append(")");

        return sb.ToString(); 
    }

    public virtual Index[] GetIndexDefinitions() 
    { 
        return null; 
    }

    public virtual IDbCommand GetInsertCommand() 
    { 
        SqlCeCommand cmd = new SqlCeCommand(); 

        // long, manual generation of the SQL and then creating the command

        return cmd; 
    }

    public IDbCommand GetUpdateCommand() 
    { 
        SqlCeCommand cmd = new SqlCeCommand(); 

        // long, manual generation of the SQL and then creating the command 

        return cmd; 
    }

    public IDbCommand GetDeleteCommand() 
    { 
        SqlCeCommand cmd = new SqlCeCommand(); 

        // long, manual generation of the SQL and then creating the command 

        return cmd; 
    }


&lt;/pre&gt;
&lt;p&gt;
Sure, I get a few bonus points for using inheritance so that each table doesn’t have
to do all of this work, but it’s still a pain.&amp;nbsp; Adding a new Table required that
I understand all of this goo, create the ColumnInfo right, know what the index stuff
is, etc.&amp;nbsp; And what happens when I need to add a field to an existing table?&amp;nbsp;
It’s not so clear.
&lt;/p&gt;
&lt;p&gt;
Now how about consuming this from the app?&amp;nbsp; When the app needs to get an Employee&amp;nbsp;
you have code like this:
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;public IEmployee[] GetAllEmployees(IDbConnection connection) 
{ 
    List&lt;IEMPLOYEE&gt;
list = new List&lt;IEMPLOYEE&gt;
(); using (SqlCeCommand command = new SqlCeCommand()) { command.CommandText = EMPLOYEES_SELECT_SQL2;
command.Connection = connection as SqlCeConnection; using (var rs = command.ExecuteResultSet(ResultSetOptions.Scrollable
| ResultSetOptions.Insensitive)) { GetEmployeeFieldOrdinals(rs, false); while (rs.Read())
{ IEmployee employee = EntityService.CreateEmployee(); employee.BadgeNumber = rs.IsDBNull(m_employeeFieldOrdinals["BadgeNumber"])
? null : rs.GetString(m_employeeFieldOrdinals["BadgeNumber"]); employee.BasePay =
rs.IsDBNull(m_employeeFieldOrdinals["EmployeeNumber"]) ? 0 : rs.GetDecimal(m_employeeFieldOrdinals["BasePay"]);
employee.DateOfHire = rs.IsDBNull(m_employeeFieldOrdinals["DateOfHire"]) ? DateTime.MinValue
: rs.GetDateTime(m_employeeFieldOrdinals["DateOfHire"]); employee.EmployeeID = rs.GetInt32(m_employeeFieldOrdinals["EmployeeID"]);
employee.FirstName = rs.GetString(m_employeeFieldOrdinals["FirstName"]); employee.LastName
= rs.GetString(m_employeeFieldOrdinals["LastName"]); string middleInitialStr = !rs.IsDBNull(m_employeeFieldOrdinals["MiddleInitial"])
? rs.GetString(m_employeeFieldOrdinals["MiddleInitial"]) : String.Empty; employee.MiddleInitial
= String.IsNullOrEmpty(middleInitialStr) ? '\0' : middleInitialStr[0]; // on and on
for another 100 lines of code) list.Add(employee); } } } return list.ToArray(); } 
&lt;/pre&gt;
&lt;p&gt;
Nevermind the fact that this could be improved a little with GetFields – the big issues
here are that you have to hard-code the SQL to get the data, then you have to parse
the results and fill out the Employee entity instance.&amp;nbsp; You do this for every
table.&amp;nbsp; You change a table, you then have to go change the SQL and every method
that touches the table.&amp;nbsp; The process is error prone, time consuming and just
not fun.&amp;nbsp; It also makes me uneasy because the test surface area needs to be big.&amp;nbsp;
How do I ensure that all places that access the table were fixed?&amp;nbsp; Unit tests
help give me some comfort, but really it has to go through full integration testing
of all features (since Employees are used by just about every feature on the clock).
&lt;/p&gt;
&lt;p&gt;
Now what would the ORM do for me here?&amp;nbsp; Without going into too much detail on
exactly how to use the ORM (we’ll look at that in another blog entry), let’s just
look at what the ORM version of things would look like.
&lt;/p&gt;
&lt;p&gt;
We’d not have any “Table” crap.&amp;nbsp; No SQL.&amp;nbsp; No building Commands and no parsing
Resultsets.&amp;nbsp; We’d just define an Entity like this:
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;[Entity] 
internal class Employee 
{ 
    [Field(IsPrimaryKey = true)] 
    public int EmployeeID { get; set; }        
    [Field] 
    public DateTime DateOfHire { get; set; } 
    [Field] 
    public string FirstName { get; set; } 
    [Field] 
    public string LastName { get; set; }

    // etc. 
}
&lt;/pre&gt;
&lt;p&gt;
Note how much cleaner this is than the Table code I had previously.&amp;nbsp; Also note
that this one class replaces *both* the Table class and the Business Object class.&amp;nbsp;
So this is much shorter.
&lt;/p&gt;
&lt;p&gt;
What about all of that create table, insert, update and delete SQL and index garbage
I had to know about, write and maintain?&amp;nbsp; Well, it’s replaced with this:
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;m_store = new DataStore(databasePath);

if (!m_store.StoreExists) 
{ 
    m_store.CreateStore(); 
}

m_store.AddType&amp;lt;Employee&amp;gt;(); 

&lt;/pre&gt;
&lt;p&gt;
That’s it.&amp;nbsp; Adding another Entity simply requires adding just one more line of
code – a call to AddType for the new Entity type.&amp;nbsp; In fact the ORM can auto-detect
all Entity types in an assembly with a single call if you want.&amp;nbsp; So that’s another
big win.&amp;nbsp; The base class garbage gets shifted into a framework that’s already
tested.&amp;nbsp; Less code for me to write means more time to solve my real problems
and less chance for me to add bugs.
&lt;/p&gt;
&lt;p&gt;
What about the long, ugly, unmaintainable query though?&amp;nbsp; Well that’s where the
ORM really, really pays off.&amp;nbsp; Getting all Employees becomes stupid simple.
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;var allEmployees = m_store.Select&amp;lt;Employee&amp;gt;();&amp;nbsp; &lt;/pre&gt;
&lt;p&gt;
Yep, that’s it. There are overloads that let you do filtering.&amp;nbsp; There are other
methods that allow you to do paging.&amp;nbsp; Creates, updates and deletes are similarly
easy.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Why did I create my own instead of using one that already exists?&amp;nbsp; Simple – there
isn’t one for the Compact Framework.&amp;nbsp; I also find that, like many existing IoC
frameworks, they try to be everything to everyone and end up overly complex.&amp;nbsp;
Another benefit to the OpenNETCF ORM is that it is fully supported on both the Compact
and Full Frameworks, so I can use it in desktop and device projects and not have to
cloud my brain with knowing multiple frameworks.&amp;nbsp; I even have a partial port
to Windows Phone (it just needs a little time to work around my use of TableDirect
in the SQL Compact implementation).&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Oh, and it’s fast.&amp;nbsp; Really fast.&amp;nbsp; Since my initial target was a device with
limited resources, I wrote the code for that environment.&amp;nbsp; The SQL Compact implementation
avoids using the query parser whenever possible because experience has taught me that
as soon as you write actual SQL, you’re going to pay an order of magnitude performance
penalty (yes, it really is that bad).&amp;nbsp; It uses TableDirect whenever possible.&amp;nbsp;
It caches type info so reflection use is kept to a bare minimum.&amp;nbsp; It caches common
commands so if SQL was necessary, it at least can reuse query plans.
&lt;/p&gt;
&lt;p&gt;
So that’s why I &lt;a href="http://orm.codeplex.com"&gt;use an ORM&lt;/a&gt;. Doing data access
in any other way has become insanity.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=8a41ba23-a3cc-4786-a672-f8d45c2f15be" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>.NET Compact Framework</category>
      <category>OpenNETCF</category>
      <category>OpenNETCF.ORM</category>
      <category>Patterns and Practices</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=bdfe97f5-3476-418c-9ef2-3db936810b2d</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,bdfe97f5-3476-418c-9ef2-3db936810b2d.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This post is part of my "Software Development" series.  <a href="http://blog.opennetcf.com/ctacke/2011/11/01/SoftwareDevelopmentSeriesTOC.aspx">The
TOC for the entire series can be found here</a>.
</p>
        <p>
          <hr />
        </p>
        <p>
Developing good software is hard.  Really hard.  Sure, anyone can buy a
book on writing software or pull up some code samples and get something that compiles
and runs, but that’s not’s really developing software.  A lot of code in the
wild – I’d bet a vast majority of it – just plain sucks.
</p>
        <p>
It’s hard to point out where the blame lies.  It seems that most developers are
environmentally or institutionally destined to write bad code. Schools teach how to
write code, but not how to architect it or to follow reasonable design practices. 
In the zeal for clarity, publishers churn out books, blogs and samples that show bad
practices (when is it ever a good idea to access a data model from your UI event handler?). 
Managers and customers alike push hard to get things done now, not necessarily done
right – only to find months or years later that doing it right would have saved a
boatload of time and money.  And let’s face it – many developers are simply showing
up to work to pull a paycheck.  You know who they are.  You’ve no doubt
worked with them in the past.  You’re probably working with them now.
</p>
        <p>
I was watching Gordon Ramsay the other day and it occurred to me that he and I are
alike in our own peculiar way.  I’m not saying that I see myself as the “Gordon
Ramsay of Software Development” – hardly -   but we share a common trait. 
Just as Gordon gets angry and starts spewing colorful language when he walks into
a crap kitchen, it bothers the hell out of me to see complete idiots in my chosen
field out there just making a mess of things.  When I see bad code – not necessarily
minor errors, or code that could be refactored and made better – but just outright
shit code that should not have occurred to a developer in the first place it pisses
me off.  By the nature of my work, often getting called in only when the project
is off the rails, I see it all the time. Code that, on review, a peer or mentor should
have seen and said “Whoa!  There’s no way that’s going into our code base”. 
Code that just makes it harder for the next person to do their job.
</p>
        <p>
In an effort to simplify things for my own code, for my customers’ code as well as
anyone who is willing to listen to my ravings, I’ve spent a lot of time building,
testing, fixing and extending tools and frameworks that many of which I turn around
and give away.  This isn’t out of altruism, no, it’s largely because I’m a lazy
developer.  I hate writing the same thing twice.  When I start a project,
I don’t want to spend large amounts of time building up the same infrastructure that
every project needs. Building up a framework for handling UI navigation isn’t what
I’d call interesting, but just about every project needs it.  Handling object
dependencies and events is common.  Writing a DAL for serializing and deserializing
entities is not just drudgery, I find it’s highly susceptible to errors because you
end up doing a lot of copy and paste.
</p>
        <p>
I have these cool tools and frameworks that I use in literally every project I work
on now.  That’s great for me, but it doesn’t really help others, right? 
Without reasonable documentation or explanation, only a small handful of people are
going to go through the effort of getting the tools and trying to understand them
– even if they are deceptively simple and could potentially save you weeks of effort.  
</p>
        <p>
So I’ve decided to put together a series of blogs over the coming weeks and months
that explain, hopefully in simple terms, what these frameworks do, how to use them,
and most importantly, why they are worth using.  There’s nothing groundbreaking
here.  I didn’t invent some new way to do things.  I’ve simply appropriated
other peoples’ ideas and extended them to work in the environments that I work.
</p>
        <p>
Generally I’ll be covering the following topics and frameworks:
</p>
        <ul>
          <li>
Dependency Injection and Inversion of Control (using OpenNETCF IoC) 
</li>
          <li>
Event Aggregation (using OpenNETCF IoC) 
</li>
          <li>
Plug-in Architectures and interface-based programming (using OpenNETCF IoC) 
</li>
          <li>
Software features as services (using OpenNETCF IoC) 
</li>
          <li>
Data Access through an ORM (using OpenNETCF ORM) 
</li>
          <li>
Parameter Checking (using OpenNETCF Extensions) 
</li>
          <li>
Exposing data services over HTTP (using Padarn) 
</li>
          <li>
Whatever else I think of 
</li>
        </ul>
        <p>
If there’s a topic you’d like me to talk about, feel free to send me an email. 
I may turn on comments here and let you post ideas, but I find that when I enable
comments on my blog, I start getting more comment spam than I really want to deal
with, so if comments are turned off just drop me a line.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=bdfe97f5-3476-418c-9ef2-3db936810b2d" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>On Software Development</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,bdfe97f5-3476-418c-9ef2-3db936810b2d.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/10/31/OnSoftwareDevelopment.aspx</link>
      <pubDate>Mon, 31 Oct 2011 16:11:24 GMT</pubDate>
      <description>&lt;p&gt;
This post is part of my "Software Development" series.&amp;nbsp; &lt;a href="http://blog.opennetcf.com/ctacke/2011/11/01/SoftwareDevelopmentSeriesTOC.aspx"&gt;The
TOC for the entire series can be found here&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;hr&gt;
&lt;/p&gt;
&lt;p&gt;
Developing good software is hard.&amp;nbsp; Really hard.&amp;nbsp; Sure, anyone can buy a
book on writing software or pull up some code samples and get something that compiles
and runs, but that’s not’s really developing software.&amp;nbsp; A lot of code in the
wild – I’d bet a vast majority of it – just plain sucks.
&lt;/p&gt;
&lt;p&gt;
It’s hard to point out where the blame lies.&amp;nbsp; It seems that most developers are
environmentally or institutionally destined to write bad code. Schools teach how to
write code, but not how to architect it or to follow reasonable design practices.&amp;nbsp;
In the zeal for clarity, publishers churn out books, blogs and samples that show bad
practices (when is it ever a good idea to access a data model from your UI event handler?).&amp;nbsp;
Managers and customers alike push hard to get things done now, not necessarily done
right – only to find months or years later that doing it right would have saved a
boatload of time and money.&amp;nbsp; And let’s face it – many developers are simply showing
up to work to pull a paycheck.&amp;nbsp; You know who they are.&amp;nbsp; You’ve no doubt
worked with them in the past.&amp;nbsp; You’re probably working with them now.
&lt;/p&gt;
&lt;p&gt;
I was watching Gordon Ramsay the other day and it occurred to me that he and I are
alike in our own peculiar way.&amp;nbsp; I’m not saying that I see myself as the “Gordon
Ramsay of Software Development” – hardly -&amp;nbsp;&amp;nbsp; but we share a common trait.&amp;nbsp;
Just as Gordon gets angry and starts spewing colorful language when he walks into
a crap kitchen, it bothers the hell out of me to see complete idiots in my chosen
field out there just making a mess of things.&amp;nbsp; When I see bad code – not necessarily
minor errors, or code that could be refactored and made better – but just outright
shit code that should not have occurred to a developer in the first place it pisses
me off.&amp;nbsp; By the nature of my work, often getting called in only when the project
is off the rails, I see it all the time. Code that, on review, a peer or mentor should
have seen and said “Whoa!&amp;nbsp; There’s no way that’s going into our code base”.&amp;nbsp;
Code that just makes it harder for the next person to do their job.
&lt;/p&gt;
&lt;p&gt;
In an effort to simplify things for my own code, for my customers’ code as well as
anyone who is willing to listen to my ravings, I’ve spent a lot of time building,
testing, fixing and extending tools and frameworks that many of which I turn around
and give away.&amp;nbsp; This isn’t out of altruism, no, it’s largely because I’m a lazy
developer.&amp;nbsp; I hate writing the same thing twice.&amp;nbsp; When I start a project,
I don’t want to spend large amounts of time building up the same infrastructure that
every project needs. Building up a framework for handling UI navigation isn’t what
I’d call interesting, but just about every project needs it.&amp;nbsp; Handling object
dependencies and events is common.&amp;nbsp; Writing a DAL for serializing and deserializing
entities is not just drudgery, I find it’s highly susceptible to errors because you
end up doing a lot of copy and paste.
&lt;/p&gt;
&lt;p&gt;
I have these cool tools and frameworks that I use in literally every project I work
on now.&amp;nbsp; That’s great for me, but it doesn’t really help others, right?&amp;nbsp;
Without reasonable documentation or explanation, only a small handful of people are
going to go through the effort of getting the tools and trying to understand them
– even if they are deceptively simple and could potentially save you weeks of effort.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
So I’ve decided to put together a series of blogs over the coming weeks and months
that explain, hopefully in simple terms, what these frameworks do, how to use them,
and most importantly, why they are worth using.&amp;nbsp; There’s nothing groundbreaking
here.&amp;nbsp; I didn’t invent some new way to do things.&amp;nbsp; I’ve simply appropriated
other peoples’ ideas and extended them to work in the environments that I work.
&lt;/p&gt;
&lt;p&gt;
Generally I’ll be covering the following topics and frameworks:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Dependency Injection and Inversion of Control (using OpenNETCF IoC) 
&lt;li&gt;
Event Aggregation (using OpenNETCF IoC) 
&lt;li&gt;
Plug-in Architectures and interface-based programming (using OpenNETCF IoC) 
&lt;li&gt;
Software features as services (using OpenNETCF IoC) 
&lt;li&gt;
Data Access through an ORM (using OpenNETCF ORM) 
&lt;li&gt;
Parameter Checking (using OpenNETCF Extensions) 
&lt;li&gt;
Exposing data services over HTTP (using Padarn) 
&lt;li&gt;
Whatever else I think of 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
If there’s a topic you’d like me to talk about, feel free to send me an email.&amp;nbsp;
I may turn on comments here and let you post ideas, but I find that when I enable
comments on my blog, I start getting more comment spam than I really want to deal
with, so if comments are turned off just drop me a line.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=bdfe97f5-3476-418c-9ef2-3db936810b2d" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>Compact Framework Code</category>
      <category>Inversion of Control</category>
      <category>OpenNETCF</category>
      <category>OpenNETCF.IoC</category>
      <category>OpenNETCF.ORM</category>
      <category>Padarn</category>
      <category>Patterns and Practices</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=daf006ad-e60d-4c19-8049-981ced9e1d3f</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,daf006ad-e60d-4c19-8049-981ced9e1d3f.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I checked in a load of updates to <a href="http://orm.codeplex.com">the
ORM project</a> earlier this week.  I've now published these changes, plus support
for byte[] Fields and some other infrastructure work as an <a href="http://orm.codeplex.com/releases/view/58673">official
release</a> (build 1.0.11006).
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=daf006ad-e60d-4c19-8049-981ced9e1d3f" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>New OpenNETCF.ORM Release</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,daf006ad-e60d-4c19-8049-981ced9e1d3f.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/01/06/NewOpenNETCFORMRelease.aspx</link>
      <pubDate>Thu, 06 Jan 2011 16:00:36 GMT</pubDate>
      <description>&lt;p&gt;
I checked in&amp;nbsp;a load of&amp;nbsp;updates to &lt;a href="http://orm.codeplex.com"&gt;the
ORM project&lt;/a&gt; earlier this week.&amp;nbsp; I've now published these changes, plus support
for byte[] Fields and some other infrastructure work as an &lt;a href="http://orm.codeplex.com/releases/view/58673"&gt;official
release&lt;/a&gt; (build 1.0.11006).
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=daf006ad-e60d-4c19-8049-981ced9e1d3f" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.ORM</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=dc205f20-ae84-4b71-8fa0-ab110f292d59</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,dc205f20-ae84-4b71-8fa0-ab110f292d59.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Occasionally we need to store data in a database that doesn't neatly fit into the
"normal" column type definitions of a database - for example we might want to store
an image or just a serialized object. The newest OpenNETCF.ORM Library provides a
simple mechanism for handling these types of objects, it's just not all that clear
from the object model how it works. I'm hoping that this post will clarify things.
</p>
        <p>
First, ORM can handle *any* type of object that is marked as a Field in an Entity
class. If the Field is an Object, however, you have to help it out by providing a
mechanism to serialize and deserialize that object.
</p>
        <p>
Let's look at a simple example. Let's say I have the following Entity definition:
</p>
        <pre class="csharp" name="code">[Entity(KeyScheme.Identity)]
public class TestTable
{
    [Field(IsPrimaryKey = true)]
    public int TestID { get; set; }

    [Field]
    public CustomObject CustomObject { get; set; }
}
</pre>
        <p>
Sure, it's likely going to have more fields, but what's important here is the CustomObject
Property that is a CustomObject class. What happens when the ORM library hits one
of these when it's doing an Insert or Select?
</p>
        <p>
If the object boils down to being an object, it calls either a Serialize or Deserialize
method, depending on which it needs, in the Entity instance itself. The expectation
is that these methods will have the following signatures (yes, I realize these should
maybe be defined in some abstract base class, but for now they aren't):
</p>
        <pre class="csharp" name="code">[Entity(KeyScheme.Identity)]
public class TestTable
{
    [Field(IsPrimaryKey = true)]
    public int TestID { get; set; }

    [Field]
    public CustomObject CustomObject { get; set; }

    public byte[] Serialize(string fieldName)
    {
        // serialize
    }

		public object Deserialize(string fieldName, byte[] data)
    {
        // deserialize
    }
}
</pre>
        <p>
What happens here is that a string representation of the Field being requested will
be passed in by the framework, and it's up to your implementation to correctly handle
it. Let's extend this example by defining our CustomObject like this:
</p>
        <pre class="csharp" name="code">public class CustomObject
{
    public string ObjectName { get; set; }
    public Guid Identifier { get; set; }
    public int SomeIntProp { get; set; }

    public CustomObject()
    {
    }

    public CustomObject(byte[] data)
    {
        // deserialization ctor
        int offset = 0;

        // get the name length
        var nameLength = BitConverter.ToInt32(data, offset);

        // get the name bytes
        offset += 4; // past the length
        this.ObjectName = Encoding.ASCII.GetString(data, offset, nameLength);

        // get the GUID
        offset += nameLength;
        byte[] guidData = new byte[16];
        // we must copy the data since Guid doesn't have a ctor that allows us to specify an offset
        Buffer.BlockCopy(data, offset, guidData, 0, guidData.Length);
        this.Identifier = new Guid(guidData);

        // get the int property
        offset += guidData.Length;
        this.SomeIntProp = BitConverter.ToInt32(data, offset);
    }

    public byte[] AsByteArray()
    {
        List<BYTE>
buffer = new List<BYTE>
(); byte[] nameData = Encoding.ASCII.GetBytes(this.ObjectName); // store the name
length buffer.AddRange(BitConverter.GetBytes(nameData.Length)); // store the name
data buffer.AddRange(nameData); // store the GUID buffer.AddRange(this.Identifier.ToByteArray());
// store the IntProp buffer.AddRange(BitConverter.GetBytes(this.SomeIntProp)); return
buffer.ToArray(); } } 
</BYTE></BYTE></pre>
        <p>
Notice that I've decided to create my own custom serialization routines for the object.
You could just as easily use a built-in serializer or whatever you'd like. I've put
the serialization routines in the custom object class itself to prevent cluttering
up my Entity definition. Now the Entity definition get's fleshed out to look like
this for the Serialize and Deserialize methods:
</p>
        <pre class="csharp" name="code">[Entity(KeyScheme.Identity)]
public class TestTable
{
    [Field(IsPrimaryKey = true)]
    public int TestID { get; set; }

    [Field]
    public CustomObject CustomObject { get; set; }

    public byte[] Serialize(string fieldName)
    {
        if (fieldName == "CustomObject")
        {
            // This will always be true in this case since CustomObject is our only
            // Object Field.  The "if" block could be omitted, but for sample 
            // clarity I'm keeping it
            if (this.CustomObject == null) return null;
            return this.CustomObject.AsByteArray();
        }

        throw new NotSupportedException();
    }

		public object Deserialize(string fieldName, byte[] data)
    {
        if (fieldName == "CustomObject")
        {
            // This will always be true in this case since CustomObject is our only
            // Object Field.  The "if" block could be omitted, but for sample 
            // clarity I'm keeping it
            return new CustomObject(data);
        }

        throw new NotSupportedException();
    }
}
</pre>
        <p>
Pretty straightforward, especially if you only have one Object Field to worry about.
Once the Serialize/Deserialize methods are implemented in the Entity, the new Entity
works just like any other entity in ORM, so you can do something like this to insert
a row and retrieve it back:
</p>
        <pre class="csharp" name="code">    var newObject = new CustomObject
    {
        ObjectName = "Object A",
        Identifier = Guid.NewGuid(),
        SomeIntProp = 12345
    };

    var testRow = new TestTable
    {
        CustomObject = newObject
    };

    Store.Insert(testRow);

    var existing = Store.Select<TESTTABLE>
().First(); 
</TESTTABLE></pre>
        <p>
I've found this to be extremely useful in a project where I had to store spectrum
data for a row. Keep in mind that if the object is of any size, it could seriously
impact your Select performance since the ORM has to select and rehydrate all of these
objects for your returned data set. Use it sparingly, and if the object is often empty,
it might pay off to put the custom object into its own child table and pull it in
as a relationship so that the Serialize/Deserialize routines only get called when
absolutely necessary.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=dc205f20-ae84-4b71-8fa0-ab110f292d59" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>ORM and Custom Object Serialization</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,dc205f20-ae84-4b71-8fa0-ab110f292d59.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/01/05/ORMAndCustomObjectSerialization.aspx</link>
      <pubDate>Wed, 05 Jan 2011 16:57:47 GMT</pubDate>
      <description>&lt;p&gt;
Occasionally we need to store data in a database that doesn't neatly fit into the
"normal" column type definitions of a database - for example we might want to store
an image or just a serialized object. The newest OpenNETCF.ORM Library provides a
simple mechanism for handling these types of objects, it's just not all that clear
from the object model how it works. I'm hoping that this post will clarify things.
&lt;/p&gt;
&lt;p&gt;
First, ORM can handle *any* type of object that is marked as a Field in an Entity
class. If the Field is an Object, however, you have to help it out by providing a
mechanism to serialize and deserialize that object.
&lt;/p&gt;
&lt;p&gt;
Let's look at a simple example. Let's say I have the following Entity definition:
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;[Entity(KeyScheme.Identity)]
public class TestTable
{
    [Field(IsPrimaryKey = true)]
    public int TestID { get; set; }

    [Field]
    public CustomObject CustomObject { get; set; }
}
&lt;/pre&gt;
&lt;p&gt;
Sure, it's likely going to have more fields, but what's important here is the CustomObject
Property that is a CustomObject class. What happens when the ORM library hits one
of these when it's doing an Insert or Select?
&lt;/p&gt;
&lt;p&gt;
If the object boils down to being an object, it calls either a Serialize or Deserialize
method, depending on which it needs, in the Entity instance itself. The expectation
is that these methods will have the following signatures (yes, I realize these should
maybe be defined in some abstract base class, but for now they aren't):
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;[Entity(KeyScheme.Identity)]
public class TestTable
{
    [Field(IsPrimaryKey = true)]
    public int TestID { get; set; }

    [Field]
    public CustomObject CustomObject { get; set; }

    public byte[] Serialize(string fieldName)
    {
        // serialize
    }

		public object Deserialize(string fieldName, byte[] data)
    {
        // deserialize
    }
}
&lt;/pre&gt;
&lt;p&gt;
What happens here is that a string representation of the Field being requested will
be passed in by the framework, and it's up to your implementation to correctly handle
it. Let's extend this example by defining our CustomObject like this:
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;public class CustomObject
{
    public string ObjectName { get; set; }
    public Guid Identifier { get; set; }
    public int SomeIntProp { get; set; }

    public CustomObject()
    {
    }

    public CustomObject(byte[] data)
    {
        // deserialization ctor
        int offset = 0;

        // get the name length
        var nameLength = BitConverter.ToInt32(data, offset);

        // get the name bytes
        offset += 4; // past the length
        this.ObjectName = Encoding.ASCII.GetString(data, offset, nameLength);

        // get the GUID
        offset += nameLength;
        byte[] guidData = new byte[16];
        // we must copy the data since Guid doesn't have a ctor that allows us to specify an offset
        Buffer.BlockCopy(data, offset, guidData, 0, guidData.Length);
        this.Identifier = new Guid(guidData);

        // get the int property
        offset += guidData.Length;
        this.SomeIntProp = BitConverter.ToInt32(data, offset);
    }

    public byte[] AsByteArray()
    {
        List&lt;BYTE&gt;
buffer = new List&lt;BYTE&gt;
(); byte[] nameData = Encoding.ASCII.GetBytes(this.ObjectName); // store the name
length buffer.AddRange(BitConverter.GetBytes(nameData.Length)); // store the name
data buffer.AddRange(nameData); // store the GUID buffer.AddRange(this.Identifier.ToByteArray());
// store the IntProp buffer.AddRange(BitConverter.GetBytes(this.SomeIntProp)); return
buffer.ToArray(); } } 
&lt;/pre&gt;
&lt;p&gt;
Notice that I've decided to create my own custom serialization routines for the object.
You could just as easily use a built-in serializer or whatever you'd like. I've put
the serialization routines in the custom object class itself to prevent cluttering
up my Entity definition. Now the Entity definition get's fleshed out to look like
this for the Serialize and Deserialize methods:
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;[Entity(KeyScheme.Identity)]
public class TestTable
{
    [Field(IsPrimaryKey = true)]
    public int TestID { get; set; }

    [Field]
    public CustomObject CustomObject { get; set; }

    public byte[] Serialize(string fieldName)
    {
        if (fieldName == "CustomObject")
        {
            // This will always be true in this case since CustomObject is our only
            // Object Field.  The "if" block could be omitted, but for sample 
            // clarity I'm keeping it
            if (this.CustomObject == null) return null;
            return this.CustomObject.AsByteArray();
        }

        throw new NotSupportedException();
    }

		public object Deserialize(string fieldName, byte[] data)
    {
        if (fieldName == "CustomObject")
        {
            // This will always be true in this case since CustomObject is our only
            // Object Field.  The "if" block could be omitted, but for sample 
            // clarity I'm keeping it
            return new CustomObject(data);
        }

        throw new NotSupportedException();
    }
}
&lt;/pre&gt;
&lt;p&gt;
Pretty straightforward, especially if you only have one Object Field to worry about.
Once the Serialize/Deserialize methods are implemented in the Entity, the new Entity
works just like any other entity in ORM, so you can do something like this to insert
a row and retrieve it back:
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;    var newObject = new CustomObject
    {
        ObjectName = "Object A",
        Identifier = Guid.NewGuid(),
        SomeIntProp = 12345
    };

    var testRow = new TestTable
    {
        CustomObject = newObject
    };

    Store.Insert(testRow);

    var existing = Store.Select&lt;TESTTABLE&gt;
().First(); 
&lt;/pre&gt;
&lt;p&gt;
I've found this to be extremely useful in a project where I had to store spectrum
data for a row. Keep in mind that if the object is of any size, it could seriously
impact your Select performance since the ORM has to select and rehydrate all of these
objects for your returned data set. Use it sparingly, and if the object is often empty,
it might pay off to put the custom object into its own child table and pull it in
as a relationship so that the Serialize/Deserialize routines only get called when
absolutely necessary.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=dc205f20-ae84-4b71-8fa0-ab110f292d59" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.ORM</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=f21b2e9e-80a6-4185-8671-dbb77f2737fd</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,f21b2e9e-80a6-4185-8671-dbb77f2737fd.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We've shipped a first version of a customer project.  That's always good news,
but the benefit to the community at large is that updates, improvements and fixes
to both the <a href="http://orm.codeplex.com/">ORM</a> and <a href="http://ioc.codeplex.com/">IoC</a> projects
from that project have now propagated to the public code bases.
</p>
        <p>
The <a href="http://ioc.codeplex.com/SourceControl/changeset/changes/55371">IoC changes</a> are
pretty minor, which tells me that it's a pretty robust and mature library on the whole.
</p>
        <p>
ORM had a <a href="http://orm.codeplex.com/SourceControl/changeset/changes/82311">load
of changes</a> in the SQL Compact implementation.  The interface for the DataStore
has expanded by several methods due to use-cases I needed methods for and it's got
a whole lot of performance improvements added.  ORM and is now shipping to real-world
customers in a handheld product, so I consider it "release" quality.
</p>
        <p>
Be aware that neither project has these changes rolled into a release package yet,
so if you want these changes, grab the latest change set from the "Source
Code" tab on the appropriate project page.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=f21b2e9e-80a6-4185-8671-dbb77f2737fd" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>Updates to ORM and IoC projects</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,f21b2e9e-80a6-4185-8671-dbb77f2737fd.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2010/12/24/UpdatesToORMAndIoCProjects.aspx</link>
      <pubDate>Fri, 24 Dec 2010 17:27:44 GMT</pubDate>
      <description>&lt;p&gt;
We've shipped a first version of a customer project.&amp;nbsp; That's always good news,
but the benefit to the community at large is that updates, improvements and fixes
to both the &lt;a href="http://orm.codeplex.com/"&gt;ORM&lt;/a&gt; and &lt;a href="http://ioc.codeplex.com/"&gt;IoC&lt;/a&gt; projects
from that project have now propagated to the public code bases.
&lt;/p&gt;
&lt;p&gt;
The &lt;a href="http://ioc.codeplex.com/SourceControl/changeset/changes/55371"&gt;IoC changes&lt;/a&gt; are
pretty minor, which tells me that it's a pretty robust and mature library on the whole.
&lt;/p&gt;
&lt;p&gt;
ORM had a &lt;a href="http://orm.codeplex.com/SourceControl/changeset/changes/82311"&gt;load
of changes&lt;/a&gt; in the SQL Compact implementation.&amp;nbsp; The interface for the DataStore
has expanded by several methods due to use-cases I needed methods for and it's got
a whole lot of performance improvements added.&amp;nbsp; ORM and is now shipping to real-world
customers in a handheld product, so I consider it "release" quality.
&lt;/p&gt;
&lt;p&gt;
Be aware that neither project has these changes rolled into a release package yet,
so if you want these changes,&amp;nbsp;grab the latest change set&amp;nbsp;from the "Source
Code" tab on the appropriate project page.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=f21b2e9e-80a6-4185-8671-dbb77f2737fd" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.IoC</category>
      <category>OpenNETCF.ORM</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=7d571ed3-17d3-479c-a71e-63646680da1d</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,7d571ed3-17d3-479c-a71e-63646680da1d.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've published a new release of the <a href="http://orm.codeplex.com">OpenNETCF.ORM
library</a>.  Some notable additions are:
</p>
        <ul>
          <li>
The ORM can now detect added Entity fields and automatically add the underlying columns
to the store</li>
          <li>
A new Select override can now filter result sets by multiple fields</li>
          <li>
I've added a skeleton for a SQLite/Windows Phone 7 project with some implementation</li>
        </ul>
        <p>
If you have a desire to help me get the WinPhone implementation completed, I really
could use the extra help.  I'm pretty busy, and without external help on this
I don't see it getting implemented any time soon (unless we get hired to do a WinPhone
project of course).
</p>
        <p>
If you're not up on what the OpenNETCF ORM library is, in short it's an open-source
ORM that actually works on the CF (NHibernate and Entity Framework do not).  
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=7d571ed3-17d3-479c-a71e-63646680da1d" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>New ORM Release</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,7d571ed3-17d3-479c-a71e-63646680da1d.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2010/10/28/NewORMRelease.aspx</link>
      <pubDate>Thu, 28 Oct 2010 17:44:56 GMT</pubDate>
      <description>&lt;p&gt;
I've published a new release of the &lt;a href="http://orm.codeplex.com"&gt;OpenNETCF.ORM
library&lt;/a&gt;.&amp;nbsp; Some notable additions are:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
The ORM can now detect added Entity fields and automatically add the underlying columns
to the store&lt;/li&gt;
&lt;li&gt;
A new&amp;nbsp;Select override can now filter result sets by multiple fields&lt;/li&gt;
&lt;li&gt;
I've added a skeleton for a SQLite/Windows Phone 7 project with some implementation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
If you have a desire to help me get the WinPhone implementation completed, I really
could use the extra help.&amp;nbsp; I'm pretty busy, and without external help on this
I don't see it getting implemented any time soon (unless we get hired to do a WinPhone
project of course).
&lt;/p&gt;
&lt;p&gt;
If you're not up on what the OpenNETCF ORM library is, in short it's an open-source
ORM that actually works on the CF (NHibernate and Entity Framework do not).&amp;nbsp; 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=7d571ed3-17d3-479c-a71e-63646680da1d" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>Compact Framework Code</category>
      <category>OpenNETCF</category>
      <category>OpenNETCF.ORM</category>
      <category>Windows Phone 7</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=f3d9849f-1cee-42df-aa76-ff1645650b37</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,f3d9849f-1cee-42df-aa76-ff1645650b37.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've made a small update to <a href="http://orm.codeplex.com">the ORM library</a>. 
I've added a SQLite assembly and started implementeing the SQLiteDataStore class. 
Note that I say "started" meaning that it's not done and ready for use (far from it
in fact).  I did do a rough pass for store (database and table) creation. 
The idea is that it gives at least some seed code for anyone interested in getting
ORM up and running on their Windows Phone using SQLite.  If you are interested
in doing this, <em>please let me know</em>.  I don't really have the time to
devote to getting this done, so I'm looking for a capable developer who would like
to take this on.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=f3d9849f-1cee-42df-aa76-ff1645650b37" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>ORM update: Added SQLite assembly for Windows Phone</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,f3d9849f-1cee-42df-aa76-ff1645650b37.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2010/09/24/ORMUpdateAddedSQLiteAssemblyForWindowsPhone.aspx</link>
      <pubDate>Fri, 24 Sep 2010 14:05:53 GMT</pubDate>
      <description>&lt;p&gt;
I've made a small update to &lt;a href="http://orm.codeplex.com"&gt;the ORM library&lt;/a&gt;.&amp;nbsp;
I've added a SQLite assembly and started implementeing the SQLiteDataStore class.&amp;nbsp;
Note that I say "started" meaning that it's not done and ready for use (far from it
in fact).&amp;nbsp; I did do a rough pass for store (database and table) creation.&amp;nbsp;
The idea is that it gives at least some seed code for anyone interested in getting
ORM up and running on their Windows Phone using SQLite.&amp;nbsp; If you are interested
in doing this, &lt;em&gt;please let me know&lt;/em&gt;.&amp;nbsp; I don't really have the time to
devote to getting this done, so I'm looking for a capable developer who would like
to take this on.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=f3d9849f-1cee-42df-aa76-ff1645650b37" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.ORM</category>
      <category>Windows Phone 7</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=02fc9abe-06a2-45bf-b3a3-e43de0036fae</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,02fc9abe-06a2-45bf-b3a3-e43de0036fae.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've re-released the <a href="http://orm.codeplex.com">OpenNETCF.ORM</a> library. 
In my haste to port the code out of the production environment I'm using it in back
to the Codeplex tree, I missed a file removal.  This broke the Codeplex release
and, of course, I didn't check it before publishing the release.  I've rectified
the problem and everything in Codeplex should now build.  If it doesn't send
me an email or add a bug to the project to let me know.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=02fc9abe-06a2-45bf-b3a3-e43de0036fae" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>OpenNETCF.ORM re-release</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,02fc9abe-06a2-45bf-b3a3-e43de0036fae.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2010/08/27/OpenNETCFORMRerelease.aspx</link>
      <pubDate>Fri, 27 Aug 2010 15:28:56 GMT</pubDate>
      <description>&lt;p&gt;
I've re-released the &lt;a href="http://orm.codeplex.com"&gt;OpenNETCF.ORM&lt;/a&gt; library.&amp;nbsp;
In my haste to port the code out of the production environment I'm using it in back
to the Codeplex tree, I missed a file removal.&amp;nbsp; This broke the Codeplex release
and, of course, I didn't check it before publishing the release.&amp;nbsp; I've rectified
the problem and everything in Codeplex should now build.&amp;nbsp; If it doesn't send
me an email or add a bug to the project to let me know.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=02fc9abe-06a2-45bf-b3a3-e43de0036fae" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.ORM</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=867ada82-046a-4638-be5c-1c93552c2e9e</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,867ada82-046a-4638-be5c-1c93552c2e9e.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've been using <a href="http://orm.codeplex.com">the OpenNETCF.ORM library</a> on
a shipping project for a while now.  As expected, as I add features to the product,
I've found problems and limitations with the ORM that I've addressed.  This morning
I merged that branch back with the trunk available on Codeplex, so there's a whole
new set of code available.  New features include:
</p>
        <ul>
          <li>
Better handling of reference fields 
</li>
          <li>
Cascading inserts 
</li>
          <li>
Cascading deletes 
</li>
          <li>
Expanded capabilities for filtering on deletes 
</li>
          <li>
Added support for more data types, including the "object" type 
</li>
          <li>
Support for ROWGUID column</li>
        </ul>
        <p>
What it really needs now is a definitive sample application and documentation. 
If you'd like to volunteer to work on either, I'd really appreciate it. 
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=867ada82-046a-4638-be5c-1c93552c2e9e" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>OpenNETCF.ORM update</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,867ada82-046a-4638-be5c-1c93552c2e9e.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2010/08/17/OpenNETCFORMUpdate.aspx</link>
      <pubDate>Tue, 17 Aug 2010 13:29:37 GMT</pubDate>
      <description>&lt;p&gt;
I've been using &lt;a href="http://orm.codeplex.com"&gt;the OpenNETCF.ORM library&lt;/a&gt; on
a shipping project for a while now.&amp;nbsp; As expected, as I add features to the product,
I've found problems and limitations with the ORM that I've addressed.&amp;nbsp; This morning
I merged that branch back with the trunk available on Codeplex, so there's a whole
new set of code available.&amp;nbsp; New features include:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Better handling of reference fields 
&lt;li&gt;
Cascading inserts 
&lt;li&gt;
Cascading deletes 
&lt;li&gt;
Expanded capabilities for filtering on deletes 
&lt;li&gt;
Added support for more data types, including the "object" type 
&lt;li&gt;
Support for ROWGUID column&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
What it really needs now is a definitive sample application and documentation.&amp;nbsp;
If you'd like to volunteer to work on either, I'd really appreciate it.&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=867ada82-046a-4638-be5c-1c93552c2e9e" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>Compact Framework Code</category>
      <category>OpenNETCF</category>
      <category>OpenNETCF.ORM</category>
      <category>Patterns and Practices</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=46339339-42bf-4d43-b1ce-29d5be121d85</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,46339339-42bf-4d43-b1ce-29d5be121d85.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Codeplex is in the process of upgrading their servers to TFS2010.  It isn't very
clear, however, how to attach to the upgraded servers from older versions of Studio
(like Studio 2008, which is required for all device development).  The answer
is that you have to install a "<a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=cf13ea45-d17b-4edc-8e6c-6c5b208ec54d&amp;displaylang=en#filelist">forward
compatibility update</a>".
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=46339339-42bf-4d43-b1ce-29d5be121d85" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>Connecting to Codeplex from Studio 2008</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,46339339-42bf-4d43-b1ce-29d5be121d85.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2010/07/12/ConnectingToCodeplexFromStudio2008.aspx</link>
      <pubDate>Mon, 12 Jul 2010 16:58:02 GMT</pubDate>
      <description>&lt;p&gt;
Codeplex is in the process of upgrading their servers to TFS2010.&amp;nbsp; It isn't very
clear, however, how to attach to the upgraded servers from older versions of Studio
(like Studio 2008, which is required for all device development).&amp;nbsp; The answer
is that you have to install a "&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=cf13ea45-d17b-4edc-8e6c-6c5b208ec54d&amp;amp;displaylang=en#filelist"&gt;forward
compatibility update&lt;/a&gt;".
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=46339339-42bf-4d43-b1ce-29d5be121d85" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.IoC</category>
      <category>OpenNETCF.ORM</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=8aa2f8fd-2604-42d6-9f7d-09fe0e4cabe0</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,8aa2f8fd-2604-42d6-9f7d-09fe0e4cabe0.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've <a href="http://blog.opennetcf.com/ctacke/2010/06/24/WhatIsYourDWR.aspx">written
about your DWR before</a>.   While deleting code is certainly a way to increase
it, it's not really the entire point.  The real point is that you should be writing
less code.  I'm a huge fan of writing less code - especially less of the redundant,
mind-numbing, why-can't-I-hire-an-intern-to-write-this code.  You know what I'm
talking about - all of that data access layer garbage that we churn out to get our
class data into and out of our relational databases.
</p>
        <p>
If your job is primarily working on one application, you probably don't do this a
whole lot, but when you are frequently starting new projects, you find yourself getting
into this tedious stuff frequently, and I really, really hate doing it.  Not
only is it torture, it's highly prone to errors since it's typically a copy, paste
and adjust-the-names process.  How often have you have to write code to generate
your database?  Does code like this look familiar?
</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> Book[]
GetAllBooks()<br />
{<br />
  var books <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> List&lt;Book&gt;();<br /><br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"> 
using</span> (SqlCeCommand cmd <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> SqlCeCommand(<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"SELECT
* FROM Book"</span>, Connection))<br />
  {<br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"><font color="#000000">    </font>using</span> (var
results <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> cmd.ExecuteResultSet(ResultSetOptions.Insensitive))<br />
    {<br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"><font color="#000000">      </font>while</span> (results.Read())<br />
      {<br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"><font color="#000000">        </font>if</span> (m_bookOrdinals.Count
== 0)<br />
        {<br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"><font color="#000000">          </font>for</span> (<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">int</span> i <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> 0;
i &lt; results.FieldCount; i++)<br />
          {<br />
            m_bookOrdinals.Add(results.GetName(i),
i);<br />
          }<br />
        }<br /><br />
        books.Add(<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">new</span> Book<br />
        {<br />
          BookID <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> results.GetInt32(m_bookOrdinals[<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"BookID"</span>]),<br />
          AuthorID <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> results.GetInt32(m_bookOrdinals[<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"AuthorID"</span>]),<br />
          Title <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> results.GetString(m_bookOrdinals[<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"Title"</span>])<br />
        });<br />
      }<br />
    }<br />
  }<br /><br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"><font color="#000000">  </font>return</span> books.ToArray();<br />
}<br /></span>
        </p>
        <p>
Well, I finally got tired of it and decided to spend some time writing code that would
free me from having to do that stuff any longer.  The result is a new, open-source
project called the <a href="http://orm.codeplex.com">OpenNETCF.ORM Framework</a>. 
It's a simple, lightweight ORM that helps take care of this tedium.  For example,
the above block of code now looks 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: blue; FONT-SIZE: 11px">public</span> Book[]
GetAllBooks()<br />
{<br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"> 
return</span> Store.Select&lt;Book&gt;();<br />
}<br /></span>
        </p>
        <p>
And it pulls all of the books from the underlying SQLCE database. Yes, it's that simple. 
Of course getting it to do that requires a little infrastructure work.  For this
one the Book class has to look like this:
</p>
        <p>
          <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px">[Entity]<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> Book<br />
{<br />
  [Field(IsIdentity=<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">true</span>,
IsPrimaryKey=<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"><font color="#000000">  </font>public</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">int</span> BookID
{ get; set; }<br /><br />
  [Field]<br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"><font color="#000000">  </font>public</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">int</span> AuthorID
{ get; set; }<br /><br />
  [Field]<br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"><font color="#000000">  </font>public</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">string</span> Title
{ get; set; }<br /><br />
  [Field(SearchOrder=FieldSearchOrder.Ascending)]<br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"><font color="#000000">  </font>public</span> BookType
BookType { get; set; }<br />
}<br /></span>
        </p>
        <p>
But that's a small price to pay in my book.  We went from 11 lines of code (not
counting brackets) to one.  Multiply that out by the number of entities, filtering
logic, paging logic and all the other code you typoically write and you'd greatly
decreased your LOC count.
</p>
        <p>
Now I'm not saying that OpenNETCF.ORM does everything that something like the Entity
Framework does.  Remember, this is a small scale framework (the core is only
14k and the SqlCE implementation adds 17k) designed for mobile and embedded systems. 
It's also put together by a team of one and as a side project while doing other work.
</p>
        <p>
What it does have, though, is performance. It's actually faster than using direct
SQL calls in many cases because it avoid the query processor whenever it can). 
It has extensibility. The source code has a full implementation for SQL CE but I've
also included the skeleton for an XML implementation for anyone who wants to try their
hand at it, and it would be pretty easy to do a MySQL or SQLite implementation as
well.  Most important, though, is that it has my commitment.  Like the <a href="http://ioc.codeplex.com/">IoC
framework</a>, I've already rolled ORM into a production application.  That means
that as I find problems, they are going to get fixed.  As I find features that
are missing that would help me get my job done, I'm going to add them.  Bottom
line is that this is not a science project that I'm doing purely for fun and that
will get abandoned when I get bored with it.
</p>
        <p>
So if you're as tired of writing DAL code as I am, give it a try.  If you like
it, let me know, or better yet update the docs or a new implementation.
</p>
        <p>
If you're ready to get started, <a href="http://orm.codeplex.com/SourceControl/list/changesets">pull
down the latest code</a> (there are no releases quite yet) and look at the test project. 
There should be enough to get you going on how to use it, but if you have questions,
feel free to <a href="http://orm.codeplex.com/Thread/List.aspx">post them</a>.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=8aa2f8fd-2604-42d6-9f7d-09fe0e4cabe0" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>Quit writing data access code</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,8aa2f8fd-2604-42d6-9f7d-09fe0e4cabe0.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2010/06/30/QuitWritingDataAccessCode.aspx</link>
      <pubDate>Wed, 30 Jun 2010 15:54:38 GMT</pubDate>
      <description>&lt;p&gt;
I've &lt;a href="http://blog.opennetcf.com/ctacke/2010/06/24/WhatIsYourDWR.aspx"&gt;written
about your DWR before&lt;/a&gt;.&amp;nbsp;&amp;nbsp; While deleting code is certainly a way to increase
it, it's not really the entire point.&amp;nbsp; The real point is that you should be writing
less code.&amp;nbsp; I'm a huge fan of writing less code - especially less of the redundant,
mind-numbing, why-can't-I-hire-an-intern-to-write-this code.&amp;nbsp; You know what I'm
talking about - all of that data access layer garbage that we churn out to get our
class data into and out of our relational databases.
&lt;/p&gt;
&lt;p&gt;
If your job is primarily working on one application, you probably don't do this a
whole lot, but when you are frequently starting new projects, you find yourself getting
into this tedious stuff frequently, and I really, really hate doing it.&amp;nbsp; Not
only is it torture, it's highly prone to errors since it's typically a copy, paste
and adjust-the-names process.&amp;nbsp; How often have you have to write code to generate
your database?&amp;nbsp; Does code like this look familiar?
&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;public&lt;/span&gt; Book[]
GetAllBooks()&lt;br&gt;
{&lt;br&gt;
&amp;nbsp; var books &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; List&amp;lt;Book&amp;gt;();&lt;br&gt;
&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&amp;nbsp;
using&lt;/span&gt; (SqlCeCommand cmd &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; SqlCeCommand(&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"SELECT
* FROM Book"&lt;/span&gt;, Connection))&lt;br&gt;
&amp;nbsp; {&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;using&lt;/span&gt; (var
results &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; cmd.ExecuteResultSet(ResultSetOptions.Insensitive))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;while&lt;/span&gt; (results.Read())&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;if&lt;/span&gt; (m_bookOrdinals.Count
== 0)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;for&lt;/span&gt; (&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;int&lt;/span&gt; i &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; 0;
i &amp;lt; results.FieldCount; i++)&lt;br&gt;
&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; m_bookOrdinals.Add(results.GetName(i),
i);&lt;br&gt;
&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; }&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; books.Add(&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;new&lt;/span&gt; Book&lt;br&gt;
&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;BookID &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; results.GetInt32(m_bookOrdinals[&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"BookID"&lt;/span&gt;]),&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AuthorID &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; results.GetInt32(m_bookOrdinals[&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"AuthorID"&lt;/span&gt;]),&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Title &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; results.GetString(m_bookOrdinals[&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"Title"&lt;/span&gt;])&lt;br&gt;
&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; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp; }&lt;br&gt;
&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&lt;font color=#000000&gt;&amp;nbsp; &lt;/font&gt;return&lt;/span&gt; books.ToArray();&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Well, I finally got tired of it and decided to spend some time writing code that would
free me from having to do that stuff any longer.&amp;nbsp; The result is a new, open-source
project called the &lt;a href="http://orm.codeplex.com"&gt;OpenNETCF.ORM Framework&lt;/a&gt;.&amp;nbsp;
It's a simple, lightweight ORM that helps take care of this tedium.&amp;nbsp; For example,
the above block of code now looks like this:
&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;public&lt;/span&gt; Book[]
GetAllBooks()&lt;br&gt;
{&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&amp;nbsp;
return&lt;/span&gt; Store.Select&amp;lt;Book&amp;gt;();&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
And it pulls all of the books from the underlying SQLCE database. Yes, it's that simple.&amp;nbsp;
Of course getting it to do that requires a little infrastructure work.&amp;nbsp; For this
one the Book class has to look like this:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"&gt;[Entity]&lt;br&gt;
&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; Book&lt;br&gt;
{&lt;br&gt;
&amp;nbsp; [Field(IsIdentity=&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;true&lt;/span&gt;,
IsPrimaryKey=&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;true&lt;/span&gt;)]&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&lt;font color=#000000&gt;&amp;nbsp; &lt;/font&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; BookID
{ get; set; }&lt;br&gt;
&lt;br&gt;
&amp;nbsp; [Field]&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&lt;font color=#000000&gt;&amp;nbsp; &lt;/font&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; AuthorID
{ get; set; }&lt;br&gt;
&lt;br&gt;
&amp;nbsp; [Field]&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&lt;font color=#000000&gt;&amp;nbsp; &lt;/font&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; Title
{ get; set; }&lt;br&gt;
&lt;br&gt;
&amp;nbsp; [Field(SearchOrder=FieldSearchOrder.Ascending)]&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&lt;font color=#000000&gt;&amp;nbsp; &lt;/font&gt;public&lt;/span&gt; BookType
BookType { get; set; }&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
But that's a small price to pay in my book.&amp;nbsp; We went from 11 lines of code (not
counting brackets) to one.&amp;nbsp; Multiply that out by the number of entities, filtering
logic, paging logic and all the other code you typoically write and you'd greatly
decreased your LOC count.
&lt;/p&gt;
&lt;p&gt;
Now I'm not saying that OpenNETCF.ORM does everything that something like the Entity
Framework does.&amp;nbsp; Remember, this is a small scale framework (the core is only
14k and the SqlCE implementation adds 17k) designed for mobile and embedded systems.&amp;nbsp;
It's also put together by a team of one and as a side project while doing other work.
&lt;/p&gt;
&lt;p&gt;
What it does have, though, is performance. It's actually faster than using direct
SQL calls in many cases because it avoid the query processor whenever it can).&amp;nbsp;
It has extensibility. The source code has a full implementation for SQL CE but I've
also included the skeleton for an XML implementation for anyone who wants to try their
hand at it, and it would be pretty easy to do a MySQL or SQLite implementation as
well.&amp;nbsp; Most important, though, is that it has my commitment.&amp;nbsp; Like the &lt;a href="http://ioc.codeplex.com/"&gt;IoC
framework&lt;/a&gt;, I've already rolled ORM into a production application.&amp;nbsp; That means
that as I find problems, they are going to get fixed.&amp;nbsp; As I find features that
are missing that would help me get my job done, I'm going to add them.&amp;nbsp; Bottom
line is that this is not a science project that I'm doing purely for fun and that
will get abandoned when I get bored with it.
&lt;/p&gt;
&lt;p&gt;
So if you're as tired of writing DAL code as I am, give it a try.&amp;nbsp; If you like
it, let me know, or better yet update the docs or a new implementation.
&lt;/p&gt;
&lt;p&gt;
If you're ready to get started, &lt;a href="http://orm.codeplex.com/SourceControl/list/changesets"&gt;pull
down the latest code&lt;/a&gt; (there are no releases quite yet) and look at the test project.&amp;nbsp;
There should be enough to get you going on how to use it, but if you have questions,
feel free to &lt;a href="http://orm.codeplex.com/Thread/List.aspx"&gt;post them&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=8aa2f8fd-2604-42d6-9f7d-09fe0e4cabe0" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>Patterns and Practices</category>
      <category>OpenNETCF.ORM</category>
    </item>
  </channel>
</rss>