<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>Genome TeamBlog</title>
    <link>http://blog.genom-e.com/</link>
    <description>Refuting the myths about object-relational mapping.</description>
    <language>en-us</language>
    <copyright>TechTalk</copyright>
    <lastBuildDate>Fri, 05 Sep 2008 14:16:03 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 1.9.7174.0</generator>
    <managingEditor>support@genom-e.com</managingEditor>
    <webMaster>support@genom-e.com</webMaster>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/GenomeTeamblog" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=4c486a95-12ad-4abf-aba1-7eb893c91ba7</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,4c486a95-12ad-4abf-aba1-7eb893c91ba7.aspx</pingback:target>
      <dc:creator>Elina Heinonen</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,4c486a95-12ad-4abf-aba1-7eb893c91ba7.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=4c486a95-12ad-4abf-aba1-7eb893c91ba7</wfw:commentRss>
      <title>Reusing query logic in LINQ</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,4c486a95-12ad-4abf-aba1-7eb893c91ba7.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/P4nZAkO818A/PermaLink,guid,4c486a95-12ad-4abf-aba1-7eb893c91ba7.aspx</link>
      <pubDate>Fri, 05 Sep 2008 14:16:03 GMT</pubDate>
      <description>&lt;font size="2" face="Arial"&gt;When writing our new messaging framework (GMX) for Genome v4, I ran into an interesting problem with LINQ. My colleague, Sztupi also ran into the same problem at almost the same time, so I thought it would make sense to write about it.&lt;/font&gt;&lt;p&gt;&lt;font size="2" face="Arial"&gt;

Before describing the problem, let me summarize some not-so-well-known facts about LINQ. If you are experienced with LINQ and the expression trees it uses, you can even skip this part and proceed from “So much for the LINQ overview” sentence to read about the problem I ran into.&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font size="2" face="Arial"&gt;

When you write a query, such as&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font size="2" face="Arial"&gt;

&lt;pre&gt;&lt;span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;from c &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;in&lt;/span&gt; customers
where c.City == &lt;span style="color: rgb(102, 102, 102); background-color: rgb(228, 228, 228); font-family: Courier New; font-size: 11px;"&gt;"London"&lt;/span&gt;
select c
&lt;/span&gt;&lt;/pre&gt;the C# compiler compiles it into a method call like this:&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font size="2" face="Arial"&gt;

&lt;pre&gt;&lt;span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;customers.Where(c =&amp;gt; c.City == &lt;span style="color: rgb(102, 102, 102); background-color: rgb(228, 228, 228); font-family: Courier New; font-size: 11px;"&gt;"London"&lt;/span&gt;)
&lt;/span&gt;&lt;/pre&gt; &lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font size="2" face="Arial"&gt;You can even write the &lt;b&gt;&lt;font face="Courier New"&gt;Where()&lt;/font&gt;&lt;/b&gt; call directly as well; you don’t have to use the "&lt;b&gt;&lt;font face="Courier New"&gt;from&lt;/font&gt;&lt;/b&gt;…" syntax. The parameter of the &lt;b&gt;&lt;font face="Courier New"&gt;Where() &lt;/font&gt;&lt;/b&gt;call is a special construct called a lambda expression, which is something very similar to an anonymous method. In fact, sometimes it is an anonymous method.&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font size="2" face="Arial"&gt;
 
Now the question is what you want to do with this lambda expression. If you want to filter customers that are already loaded into the memory, you want to have an anonymous method compiled from the lambda. However, if the customers reside in the database or in an XML file, you actually never want to evaluate the lambda as a .NET method call, but rather you want to transform it to SQL or XPath and let the underlying engine execute it. In this case, the anonymous method is not a good option, as it would be very hard to find out from the compiled CLR code that the method wanted to compare the City field to "London". &lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font size="2" face="Arial"&gt;
 
And here comes the big trick of LINQ. The C# compiler decides during compile time whether to compile the lambda expression to an anonymous method, or to an expression tree initialization code. If it compiles it to expression tree initialization, then during runtime, a new expression tree will be created whenever this &lt;b&gt;&lt;font face="Courier New"&gt;Where() &lt;/font&gt;&lt;/b&gt;method is called, and this expression tree will represent the lambda expression you just described. O/RM engines like Genome can take this expression tree and transform it to SQL. &lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font size="2" face="Arial"&gt;
 
The only question remains is how the C# compiler can decide whether to compile the lambda to an anonymous method or to expression tree initialization. This decision is done by analyzing the parameter types of the &lt;b&gt;&lt;font face="Courier New"&gt;Where() &lt;/font&gt;&lt;/b&gt;method you are actually about to call. If the &lt;b&gt;&lt;font face="Courier New"&gt;Where() &lt;/font&gt;&lt;/b&gt;method takes a delegate as a parameter, it compiles to an anonymous method, and if it takes an &lt;b&gt;&lt;font face="Courier New"&gt;Expression&lt;/font&gt;&lt;/b&gt;&lt;t&gt;&lt;b&gt;&lt;font face="Courier New"&gt;&amp;lt;T&amp;gt;&lt;/font&gt;&lt;/b&gt; parameter, it compiles to expression initialization.&lt;/t&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font size="2" face="Arial"&gt;
 
It is good to know that the LambdaExpression class has a &lt;b&gt;&lt;font face="Courier New"&gt;Compile()&lt;/font&gt;&lt;/b&gt; method, that can be used to compile the expression tree to a delegate. We don’t have a transformation in the other direction however, so you cannot get an expression tree from a delegate.&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font size="2" face="Arial"&gt;
&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=4c486a95-12ad-4abf-aba1-7eb893c91ba7"/&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,4c486a95-12ad-4abf-aba1-7eb893c91ba7.aspx</comments>
      <category>Genome</category>
      <category>Linq</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,4c486a95-12ad-4abf-aba1-7eb893c91ba7.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=042bd0e1-126b-4580-b642-52bce9f810fc</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,042bd0e1-126b-4580-b642-52bce9f810fc.aspx</pingback:target>
      <dc:creator>Elina Heinonen</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,042bd0e1-126b-4580-b642-52bce9f810fc.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=042bd0e1-126b-4580-b642-52bce9f810fc</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Microsoft has released .NET Framework 3.5. service pack 1 beta. For all Genome users:
be aware that this package rather quietly also contains an SP2 beta for the .NET 2.0
Framework, which cannot be deployed alone. There is not too much information available
on its exact contents (see <a href="http://readcommit.blogspot.com/2008/05/microsoft-net-framework-20-service-pack.html">http://readcommit.blogspot.com/2008/05/microsoft-net-framework-20-service-pack.html</a>).
</p>
        <p>
Be warned that it is possible that a Genome schema compiled with the SP beta may not
load on a machine without the SP beta (which is usual for production servers), yielding
the following error:
</p>
        <p>
          <i>SerializationException: The object with ID 40221 implements the IObjectReference
interface for which all dependencies cannot be resolved. The likely cause is two instances
of IObjectReference that have a mutual dependency on each other.]</i>
        </p>
        <p>
We are sorry about any inconvenience caused. This issue may occur with Genome V3.3.4.38
and we are currently investigating if others are affected. We are providing feedback
on this issue to Microsoft and hope that it will be resolved with the release - in
the meantime, please make sure that deployment packages are generated on a machine
that does not have SP1 beta installed!
</p>
        <img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=042bd0e1-126b-4580-b642-52bce9f810fc" />
      </body>
      <title>Caution: hold off MS .NET 3.5 SP1 for the moment</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,042bd0e1-126b-4580-b642-52bce9f810fc.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/DnUd9ax1Kjk/PermaLink,guid,042bd0e1-126b-4580-b642-52bce9f810fc.aspx</link>
      <pubDate>Tue, 01 Jul 2008 09:30:48 GMT</pubDate>
      <description>
&lt;p&gt;
Microsoft has released .NET Framework 3.5. service pack 1 beta. For all Genome users:
be aware that this package rather quietly also contains an SP2 beta for the .NET 2.0
Framework, which cannot be deployed alone. There is not too much information available
on its exact contents (see &lt;a href="http://readcommit.blogspot.com/2008/05/microsoft-net-framework-20-service-pack.html"&gt;http://readcommit.blogspot.com/2008/05/microsoft-net-framework-20-service-pack.html&lt;/a&gt;).
&lt;/p&gt;
&lt;p&gt;
Be warned that it is possible that a Genome schema compiled with the SP beta may not
load on a machine without the SP beta (which is usual for production servers), yielding
the following error:
&lt;/p&gt;
&lt;p&gt;
&lt;i&gt;SerializationException: The object with ID 40221 implements the IObjectReference
interface for which all dependencies cannot be resolved. The likely cause is two instances
of IObjectReference that have a mutual dependency on each other.]&lt;/i&gt;
&lt;/p&gt;
&lt;p&gt;
We are sorry about any inconvenience caused. This issue may occur with Genome V3.3.4.38
and we are currently investigating if others are affected. We are providing feedback
on this issue to Microsoft and hope that it will be resolved with the release - in
the meantime, please make sure that deployment packages are generated on a machine
that does not have SP1 beta installed!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=042bd0e1-126b-4580-b642-52bce9f810fc" /&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,042bd0e1-126b-4580-b642-52bce9f810fc.aspx</comments>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,042bd0e1-126b-4580-b642-52bce9f810fc.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=8044083d-8153-4046-8601-ec3556f7adaf</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,8044083d-8153-4046-8601-ec3556f7adaf.aspx</pingback:target>
      <dc:creator>Elina Heinonen</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,8044083d-8153-4046-8601-ec3556f7adaf.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=8044083d-8153-4046-8601-ec3556f7adaf</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <title>Installing large numbers of files with WIX</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,8044083d-8153-4046-8601-ec3556f7adaf.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/DYilphgNGS0/PermaLink,guid,8044083d-8153-4046-8601-ec3556f7adaf.aspx</link>
      <pubDate>Fri, 27 Jun 2008 13:10:30 GMT</pubDate>
      <description>&lt;p&gt;
Many posts (e.g.: &lt;a href="http://blog.deploymentengineering.com/2007/06/dealing-with-very-large-number-of-files.html"&gt;http://blog.deploymentengineering.com/2007/06/dealing-with-very-large-number-of-files.html&lt;/a&gt;, &lt;a href="http://www.wintellect.com/cs/blogs/jrobbins/archive/2007/10/19/wix-the-pain-of-wix-part-2-of-3.aspx"&gt;http://www.wintellect.com/cs/blogs/jrobbins/archive/2007/10/19/wix-the-pain-of-wix-part-2-of-3.aspx&lt;/a&gt;, &lt;a href="http://blog.deploymentengineering.com/2007/06/burning-in-hell-with-heat.html"&gt;http://blog.deploymentengineering.com/2007/06/burning-in-hell-with-heat.html&lt;/a&gt;)
have been written about the problem of adding large number of files to a WIX installer.
This problem is the most painful when you want to add content files that do not really
have any special purpose, but just have to be there (e.g. code samples or source code
packages).
&lt;/p&gt;
&lt;p&gt;&lt;?xml:namespace prefix = o /&gt;
I also struggled with this problem, and finally I found myself creating a small MsBuild
tool (WixFolderInclude.targets) that you can include in your WIX project and use to
generate file installers for entire folders on the disk. :-) I call it a tool, as
I don’t have a better name for it, but it is not (only) an MsBuild target, nor is
it a Task. Actually it is a WIX MsBuild extension, but WIX already has a “WIX extension”
term, which is something else. So let’s stick to “tool”.&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;u&gt;The WixFolderInclude tool&lt;/u&gt;
&lt;/p&gt;
&lt;p&gt;
Let’s see how you can use this tool; it was tested with the latest WIX framework (v3.0.4220),
but it probably works with older v3x versions as well. I’m assuming that you are more
or less familiar with the WIX and MsBuild concepts. If not, you can grab the necessary
information quickly from Gábor Deák Jahn's &lt;a href="http://www.tramontana.co.hu/wix/"&gt;WiX
Tutorial&lt;/a&gt; and the MSDN docs.
&lt;/p&gt;
&lt;p&gt;
WIX projects (.wixproj) are MsBuild projects, and you can extend them with other MsBuild
property definitions or targets. One option is to modify the wixproj file in a text
editor… This is fine, but I like the WIX project to open in Visual Studio, and in
this case modifying the project file is not easy. Instead, I usually always start
by creating a “Build.properties” file in the WIX project (it has type “Content” so
it does not modify the WIX compilation), where I can write my MsBuild extensions.
I have to modify the project file only once, when I include the Build.properties file.
I usually include it directly before the wix.targets import:
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;lt;/&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;ItemGroup&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;/i&gt;
&lt;br&gt;
&lt;b&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;Import&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;Project&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;=&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;"&lt;span style="COLOR: blue"&gt;$(MSBuildProjectDirectory)\Build.properties&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;
&lt;br&gt;
&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;Import&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;Project&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;=&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;"&lt;span style="COLOR: blue"&gt;$(WixTargetsPath)&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US&gt;
&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;&lt;/i&gt;
&lt;/p&gt;
&lt;p&gt;
But you can directly write into the project file as well, if you don’t use the VS
integration.
&lt;/p&gt;
&lt;p&gt;
Let’s take a very simple example: I would like to include two code samples in the
installer. They are located in some folder (C:\Temp\ConsoleApplication1 and C:\Temp\WebApplication1)
and I would like to install them in a “Samples” folder inside the program files entry
of my installed application. Of course both samples contain sub-folders that I also
want to include. 
&lt;/p&gt;
&lt;p&gt;
To achieve that with my tool,
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;span lang=EN-US&gt;you have to define MsBuild project items that describe the aspects
of the installation of these folders&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt; 
&lt;li&gt;
&lt;span lang=EN-US&gt;you have to define some property to utilize my tool&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt; 
&lt;li&gt;
&lt;span lang=EN-US&gt;the tool generates some temporary WIX fragment files during compilation
(and includes them in the compilation), which contain the definition of the Directory/Component/File
structure and a component group that gathers the components generated for the files
in the directory structure.&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt; 
&lt;li&gt;
&lt;span lang=EN-US&gt;&lt;span&gt;y&lt;/span&gt;&lt;/span&gt;&lt;span lang=EN-US&gt;ou have to include references
to the generated component groups in the installation features of your choice in the
normal wxs files (e.g. Program.wxs).&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
So first, let’s create the folder descriptions for my sample. The tool searches for
project items called “WixFolderInclude”, so we have to create such items for the folders
we want to include:
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;ItemGroup&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;ConsoleApplication1Files&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;Include&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;=&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;"&lt;span style="COLOR: blue"&gt;C:\temp\ConsoleApplication1\**&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; /&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;WixFolderInclude&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;Include&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;=&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;"&lt;span style="COLOR: blue"&gt;ConsoleApplication1Folder&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;SourceFiles&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;@(ConsoleApplication1Files)&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;SourceFiles&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;RootPath&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;C:\temp\ConsoleApplication1&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;RootPath&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;ParentDirectoryRef&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;Dir_Samples&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;ParentDirectoryRef&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;WixFolderInclude&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;br&gt;
&amp;lt;/&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;ItemGroup&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;o:p&gt;
&lt;br&gt;
&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;ItemGroup&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;WebApplication1Files&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;Include&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;=&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;"&lt;span style="COLOR: blue"&gt;C:\temp\WebApplication1\**&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;Exclude&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;*.scc&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; /&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;WixFolderInclude&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;Include&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;=&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;"&lt;span style="COLOR: blue"&gt;WebApplication1Folder&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;SourceFiles&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;@(WebApplication1Files)&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;SourceFiles&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;RootPath&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;C:\temp\WebApplication1Files&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;RootPath&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;ParentDirectoryRef&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;Dir_Samples&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;ParentDirectoryRef&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;WixFolderInclude&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;br&gt;
&amp;lt;/&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;ItemGroup&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
As you can see, you can define the set of files to be included with the standard possibilities
of MsBuild, so you can include deep folder structures, exclude files, or even list
the files one-by-one. In the example here I have excluded the source-control info
files (*.scc) from the second sample.
&lt;/p&gt;
&lt;p&gt;
In the WixFolderInclude items, you have to note the following things.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;span lang=EN-US&gt;The main entry (ConsoleApplication1Folder and WebApplication1Folder)
describes the name of the folder installation. The generated component group ID will
be based on this name, so you can use any meaningful name here, not necessarily the
folder name.&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt; 
&lt;li&gt;
&lt;span lang=EN-US&gt;The “SourceFiles” metadata should contain the files to be included
in this set (unfortunately, you cannot use wildcards here directly, so you have to
create a separate item for them). 
&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt; 
&lt;li&gt;
&lt;span lang=EN-US&gt;The “RootPath” metadata contains the folder root of the folder set
to be included in the installer. This could also be derived from the source file set
(by taking the common root folder), but I like to have it more explicit, like this.&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt; 
&lt;li&gt;
&lt;span lang=EN-US&gt;The “ParentDirectoryRef” metadata specifies the ID of the &amp;lt;Directory&amp;gt;,
where the folder should be included in the installer. Now I have created a directory
(Dir_Samples) for the Samples folder in the program files, so I have specified that
as parent.&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
As we are ready with the definition, the next step is to set up the tool. It is very
simple; you just have to include the following lines in the Build.properties (or the
project file):
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;Import&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;Project&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;=&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;"&lt;span style="COLOR: blue"&gt;$(MSBuildProjectDirectory)\Microsoft.Sdc.Tasks\Microsoft.Sdc.Common.tasks&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; /&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;PropertyGroup&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;CustomAfterWixTargets&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;$(MSBuildProjectDirectory)\WixFolderInclude.targets&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;CustomAfterWixTargets&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;br&gt;
&amp;lt;/&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;PropertyGroup&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
The value of the CustomAfterWixTargets should point to the tool file. If you have
it in the project folder, you can use the setting above directly. Also note that the
tool uses the Microsofr.Sdc.Tasks library (&lt;a href="http://www.codeplex.com/sdctasks"&gt;http://www.codeplex.com/sdctasks&lt;/a&gt;).
I have tested it with the latest version (2.1.3071.0), but it might work with older
versions as well. You should import the Microsoft.Sdc.Common.tasks file only once,
so if you have already imported it in your project, you can skip that line. 
&lt;/p&gt;
&lt;p&gt;
Now we are done with the entries in the Build.properties, so let’s include the folders
in the installer itself. As I have mentioned, the tool generates fragments that contain
a component group for each included folder. The component group is named as follows:
CG_&lt;i&gt;WixFolderInclude-name&lt;/i&gt;. In our case, these are &lt;i&gt;CG_ConsoleApplication1Folder&lt;/i&gt; and &lt;i&gt;CG_WebApplication1Folder&lt;/i&gt;.
So let’s include them in the main feature now:
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;Product &lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;...&amp;gt;&lt;br&gt;
&amp;nbsp; ...&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;
&amp;lt;!--&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'"&gt; setup
the folder structure &lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;--&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;br&gt;
&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;Directory&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;Id&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;=&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;"&lt;span style="COLOR: blue"&gt;TARGETDIR&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;Name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;SourceDir&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;Directory&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;Id&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;=&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;"&lt;span style="COLOR: blue"&gt;ProgramFilesFolder&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;Directory&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;Id&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;=&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;"&lt;span style="COLOR: blue"&gt;INSTALLLOCATION&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;Name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;WixProject1&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;Directory&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;Id&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;=&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;"&lt;span style="COLOR: blue"&gt;Dir_Samples&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;Name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Samples&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;Directory&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;Directory&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;Directory&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;br&gt;
&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;Directory&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;
&amp;lt;!--&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'"&gt; include
the generated component groups to the main feature &lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;--&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;br&gt;
&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;Feature&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;Id&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;=&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;"&lt;span style="COLOR: blue"&gt;ProductFeature&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;Title&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;WixProject1&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;Level&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;1&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;ComponentGroupRef&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;Id&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;=&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;"&lt;span style="COLOR: blue"&gt;CG_ConsoleApplication1Folder&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;/&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;ComponentGroupRef&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;Id&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;=&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;"&lt;span style="COLOR: blue"&gt;CG_WebApplication1Folder &lt;/span&gt;"&lt;span style="COLOR: blue"&gt;/&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;Feature&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;br&gt;
&amp;lt;/&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;Product&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span lang=EN-US&gt;And that’s it. We are ready to compile!&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;u&gt;Fine tuning&lt;/u&gt;
&lt;/p&gt;
&lt;p&gt;
The tool supports some additional configuration options, mainly for debugging purposes:
you can specify the folder where the temporary files are stored (by default, it is
the value of %TMP% environment variable) and whether it should keep the temp files
(by default, it deletes them after compilation). These settings can be overridden
by including the following lines in the Build.properties.
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;PropertyGroup&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;br&gt;
&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;WixFolderIncludeTempDir&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;C:\Temp&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;WixFolderIncludeTempDir&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;WixFolderIncludeKeepTempFiles&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;true&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;WixFolderIncludeKeepTempFiles&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;br&gt;
&amp;lt;/&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;PropertyGroup&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;u&gt;Possible problems&lt;/u&gt;
&lt;/p&gt;
&lt;p&gt;
Of course, life is not that easy... so you might encounter problems with using this
tool as well. One is that it kills MsBuild’s up-to-date detection, so it will recompile
the project even if nothing has changed. I think this could be solved by specifying
some smart output tags on the target, but it is not easy, and usually I want to be
sure that the installer package is fully recompiled anyway.
&lt;/p&gt;
&lt;p&gt;
The other – probably more painful – problem is that you cannot include additional
files from WIX to a subfolder of an included directory. We had this problem when we
wanted to create a shortcut to the solution files of the installed samples. The problem
is that since the IDs that the Sdc Fragment task generates are GUIDs, you have no
chance of guessing what the subfolder’s ID was.
&lt;/p&gt;
&lt;p&gt;
I have extended the WixFolderInclude.targets to support generating deterministic names
for some selected folders. The folders to be selected can be defined with the “DeterministicFolders”
metadata tag of the WixFolderInclude item. The value should be a semicolon-separated
list of folders relative to the RootPath. Please note that as these are folders, you
cannot really use MsBuild’s wildcard support, but you have to type these folder names
manually. Let’s suppose that we have a Documentation folder inside the ConsoleApplication1
sample, which we might be able to extend from WIX later. We have to define this as
the following:
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;ItemGroup&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;ConsoleApplication1Files&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;Include&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;=&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;"&lt;span style="COLOR: blue"&gt;C:\temp\ConsoleApplication1\**&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; /&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;WixFolderInclude&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;Include&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;=&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;"&lt;span style="COLOR: blue"&gt;ConsoleApplication1Folder&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;SourceFiles&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;@(ConsoleApplication1Files)&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;SourceFiles&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;RootPath&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;C:\temp\ConsoleApplication1&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;RootPath&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;ParentDirectoryRef&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;Dir_Samples&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;ParentDirectoryRef&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;b&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;DeterministicFolders&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;Documentation&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;DeterministicFolders&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;
&lt;br&gt;
&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;
&amp;lt;/&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;WixFolderInclude&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;br&gt;
&amp;lt;/&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;ItemGroup&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;&lt;/i&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span lang=EN-US&gt;As a result, the ID for the Documentation’s &amp;lt;Directory&amp;gt; element
will be: Dir_ConsoleApplication1Folder_Documentation, so we can extend it from our
Product.wxs:&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;DirectoryRef&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;Id&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;=&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;"&lt;span style="COLOR: blue"&gt;Dir_ConsoleApplication1Folder_Documentation&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;Component&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;Id&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;=&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;"&lt;span style="COLOR: blue"&gt;C_AdditionalFile&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;Guid&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;5D8142C1-...&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;File&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;Name&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;=&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;"&lt;span style="COLOR: blue"&gt;AdditionalFile.txt&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;Source&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;C:\Temp\AdditionalFile.txt&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; /&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;Component&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;br&gt;
&amp;lt;/&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: rgb(163,21,21); FONT-FAMILY: 'Courier New'"&gt;DirectoryRef&lt;/span&gt;&lt;span lang=EN-US&gt;&amp;gt;&lt;o:p&gt;
&lt;br&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;u&gt;Attachment&lt;/u&gt;
&lt;/p&gt;
&lt;p&gt;
In the attached ZIP file, you will find the WixFolderInclude.targets file, and also
the sample that I have used here to demonstrate the features (without the silly ConsoleApplication1
and WebApplication1 folders). Feel free to use them!
&lt;/p&gt;
&lt;a href="http://blog.genom-e.com/content/binary/ManyWixFiles.zip"&gt;ManyWixFiles.zip
(347.55 KB)&lt;/a&gt;
&lt;br&gt;
&lt;font color=#808080&gt;&lt;b&gt;
&lt;br&gt;
Posted by Gáspár&lt;/b&gt;&lt;/font&gt;
&lt;br&gt;
&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=8044083d-8153-4046-8601-ec3556f7adaf" /&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,8044083d-8153-4046-8601-ec3556f7adaf.aspx</comments>
      <category>MSBuild</category>
      <category>WIX</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,8044083d-8153-4046-8601-ec3556f7adaf.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=0cf64fa1-221b-4530-a70b-7780b92c0975</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,0cf64fa1-221b-4530-a70b-7780b92c0975.aspx</pingback:target>
      <dc:creator>Christian Hassa</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,0cf64fa1-221b-4530-a70b-7780b92c0975.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=0cf64fa1-221b-4530-a70b-7780b92c0975</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I hadn’t touched the topic of web service proxy generation for a long time, but in
order to fine tune our new message contract generation framework for Genome, I had
to check it out once more.
</p>
        <p>
My concrete problem is very simple: I want to generate a proxy for a web service,
but instead of generating some DTO types based on the wsdl, I would like to use my
DTO classes that are already implemented (I know that the wsdl-generated ones are
just fine, but mine are a little bit better). 
</p>
        <p>
The old solution was to let Visual Studio generate the proxy code, and remove the
shared type from it. And hope that you don’t have to update it too often, because
you will have to do this again. It seems that with the web service proxy there are
no real improvements. Although wsdl.exe has some nice settings, like /sharetypes,
you cannot invoke it from the “Add Web Reference” dialog. So you have to complicate
the development workflow anyway. I wonder why MS did not implement a backdoor, by
which I could provide additional wsdl.exe parameters…
</p>
        <p>
The better news is that the WCF client generator can also generate clients for web
services. And in the “Add Service Reference” dialog, you can even configure it to
reuse types from existing assemblies, if they are referenced in the client project.
Super! This is what I wanted. But it does not work :-( … At least not if the service
is an ASMX web service (it seems to work fine for WCF services). It still generates
my DTO classes. 
</p>
        <p>
I have played a lot with it. It seems that the problem is that it does not recognize
the matching DTO class, because it is annotated with XML serializer attributes ([XmlType],
etc.) and not with WCF attributes. Indeed, if I attribute the class with [DataContract]
and [DataMember] attributes, it finds it! However, there is a checking mechanism in
the client generator that can check whether the reused type matches the wsdl definition.
And it is this that seems to fail, even if I apply exactly the same attributes as
it would generate. I have looked around, and it seems that this checking mechanism
might fail even for WCF classes. 
</p>
        <p>
This is a trap. There is a validation framework that provides false validation errors
and cannot even be switched off. So I’m still exactly where I was 5 years ago: manually
removing the generated types from reference.cs.<br /></p>
        <p>
          <font size="1">Posted by <a href="mailto:gn@tec_no_spam_htalk.at">Gáspár</a></font>
        </p>
        <img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=0cf64fa1-221b-4530-a70b-7780b92c0975" />
      </body>
      <title>Web Service proxies and shared types</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,0cf64fa1-221b-4530-a70b-7780b92c0975.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/9EeCbv4Q5fU/PermaLink,guid,0cf64fa1-221b-4530-a70b-7780b92c0975.aspx</link>
      <pubDate>Tue, 20 May 2008 12:32:14 GMT</pubDate>
      <description>&lt;p&gt;
I hadn’t touched the topic of web service proxy generation for a long time, but in
order to fine tune our new message contract generation framework for Genome, I had
to check it out once more.
&lt;/p&gt;
&lt;p&gt;
My concrete problem is very simple: I want to generate a proxy for a web service,
but instead of generating some DTO types based on the wsdl, I would like to use my
DTO classes that are already implemented (I know that the wsdl-generated ones are
just fine, but mine are a little bit better). 
&lt;/p&gt;
&lt;p&gt;
The old solution was to let Visual Studio generate the proxy code, and remove the
shared type from it. And hope that you don’t have to update it too often, because
you will have to do this again. It seems that with the web service proxy there are
no real improvements. Although wsdl.exe has some nice settings, like /sharetypes,
you cannot invoke it from the “Add Web Reference” dialog. So you have to complicate
the development workflow anyway. I wonder why MS did not implement a backdoor, by
which I could provide additional wsdl.exe parameters…
&lt;/p&gt;
&lt;p&gt;
The better news is that the WCF client generator can also generate clients for web
services. And in the “Add Service Reference” dialog, you can even configure it to
reuse types from existing assemblies, if they are referenced in the client project.
Super! This is what I wanted. But it does not work :-( … At least not if the service
is an ASMX web service (it seems to work fine for WCF services). It still generates
my DTO classes. 
&lt;/p&gt;
&lt;p&gt;
I have played a lot with it. It seems that the problem is that it does not recognize
the matching DTO class, because it is annotated with XML serializer attributes ([XmlType],
etc.) and not with WCF attributes. Indeed, if I attribute the class with [DataContract]
and [DataMember] attributes, it finds it! However, there is a checking mechanism in
the client generator that can check whether the reused type matches the wsdl definition.
And it is this that seems to fail, even if I apply exactly the same attributes as
it would generate. I have looked around, and it seems that this checking mechanism
might fail even for WCF classes. 
&lt;/p&gt;
&lt;p&gt;
This is a trap. There is a validation framework that provides false validation errors
and cannot even be switched off. So I’m still exactly where I was 5 years ago: manually
removing the generated types from reference.cs.&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font size=1&gt;Posted by &lt;a href="mailto:gn@tec_no_spam_htalk.at"&gt;Gáspár&lt;/a&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=0cf64fa1-221b-4530-a70b-7780b92c0975" /&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,0cf64fa1-221b-4530-a70b-7780b92c0975.aspx</comments>
      <category>Genome</category>
      <category>WCF</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,0cf64fa1-221b-4530-a70b-7780b92c0975.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=8d2645c0-66a8-4064-b266-15a4d0464723</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,8d2645c0-66a8-4064-b266-15a4d0464723.aspx</pingback:target>
      <dc:creator>Christian Hassa</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,8d2645c0-66a8-4064-b266-15a4d0464723.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=8d2645c0-66a8-4064-b266-15a4d0464723</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
No, this article does not nag about some code I've seen that misuses new features.
This is how I did it - on purpose.
</p>
        <p>
I've always disliked the way I usually set up data in the database for testing: recreate
the database, create the domain objects, setting all the necessary properties, commit
the context. Take this code for example: 
</p>
        <pre class="sourceCode">DataDomainSchema schema = DataDomainSchema.LoadFrom("SomeMappingFile");
schema.CreateDbSchema(connStr);

DataDomain dd = new DataDomain(schema, connStr);

using (Context.Push(ShortRunningTransactionContext.Create()))
{
  Customer tt = dd.New&lt;Customer&gt;();
  tt.Name = "TechTalk";

  RootProject tt_hk = dd.New&lt;RootProject&gt;();
  tt_hk.Name = "Housekeeping";

  ChildProject tt_hk_hol = dd.New&lt;ChildProject&gt;();
  tt_hk_hol.Name = "Holiday";
  tt_hk.ChildProjects.Add(tt_hk_hol);

  ChildProject tt_hk_ill = dd.New&lt;ChildProject&gt;();
  tt_hk_ill.Name = "Illness";

  tt_hk.ChildProjects.Add(tt_hk_ill);

  tt.RootProjects.Add(tt_hk);

  RootProject tt_g = dd.New&lt;RootProject&gt;();
  tt_g.Name = "Genome";

  ChildProject tt_g_dev = dd.New&lt;ChildProject&gt;();
  tt_g_dev.Name = "Development";
  tt_g.ChildProjects.Add(tt_g_dev);

  ChildProject tt_g_mnt = dd.New&lt;ChildProject&gt;();
  tt_g_mnt.Name = "Maintenance";
  tt_g.ChildProjects.Add(tt_g_mnt);
  tt.RootProjects.Add(tt_g);

  Context.CommitCurrent();
}</pre>
        <p>
What I dislike in this is the 'setting all the necessary properties' part. Part of
it is that it's hard to follow the hierarchy of the objects. 
</p>
        <p>
The other is that I'm lazy. 
</p>
        <p>
Even if I'm typing with considerable speed - and keep pressing ctrl+(alt)+space and
let ReSharper do the rest - I still hate it for its repetitiousness. I always wanted
to have something like <a href="http://rails.rubyonrails.com/classes/Fixtures.html">ActiveRecord's
Fixtures</a> in Rails - but I never had the time to implement it. Yeah, typical excuse,
and that's how we usually <i>lose</i> development time even in the short run, <b><u>so</u></b> I
know I'll have do it the next time I need to create test data.
</p>
        <p>
Sure, I could always create builder methods for every type to handle, passing in the
property values and collections etc, but even <i>creating</i> those is yet another
repetitious task. I always longed for some more 'elegant' write-once-use-everywhere
kind of framework. So when I read <a href="http://blog.bittercoder.com/PermaLink,guid,d1831805-dbf7-4b74-a6fd-2e9ed437c3d9.aspx">this
post</a>, I thought, maybe I can get away with writing a simple, but usable enough,
initializer helper extension. Here's the resulting initializing code:
</p>
        <pre class="sourceCode">...

using (Context.Push(ShortRunningTransactionContext.Create()))
{
  dd.Init&lt;Customer&gt;().As(
     Name =&gt; "TechTalk",
     RootProjects =&gt; new Project[] {
       dd.Init&lt;RootProject&gt;().As(
         Name =&gt; "Housekeeping", 
         ChildProjects =&gt; new Project[] {
           dd.Init&lt;ChildProject&gt;().As(Name =&gt; "Holiday"),
           dd.Init&lt;ChildProject&gt;().As(Name =&gt; "Illness")
         }),
       dd.Init&lt;RootProject&gt;().As(
         Name =&gt; "Genome", 
         ChildProjects =&gt; new Project[] {
           dd.Init&lt;ChildProject&gt;().As(Name =&gt; "Development"),
           dd.Init&lt;ChildProject&gt;().As(Name =&gt; "Maintenance")
         })
       });

  Context.CommitCurrent();
}</pre>
        <p>
Prettier to the eye - but unfortunately, it's still not practical enough. For one
thing, it’s easy to represent a tree this way, but it still doesn't offer a
solution for many-to-many relations. That's a lesser concern though, and I have ideas
for overcoming this (but haven’t done it so far due to lack of time, again).
A greater problem is that it's not type safe: the parameter names of the lambdas (Name,
RootProjects, ChildProjects) are just that - names, aliases; they are not checked
during compile time. Even as a dynamic typed language advocate, I don't like too much
dynamic behavior in statically type languages - that usually results in little gain
if any, while losing their advantages, even 'developer-side' ones, like refactoring
or intellisense support.
</p>
        <p>
So, no conclusions there - I don't know which way I prefer yet. It seems that I <i>really</i> will
have to go on and write some xml-file based initialization library (which will share
some of the abovementioned problems of the non-static languages, of course, but renaming
those properties in the config by hand which you just modified in the code at least <i>feels</i> a
bit more normal).
</p>
        <p>
Still, if you're interested, here's the extension for doing the job:
</p>
        <pre class="sourceCode">public static class DataDomainInitializerExtension

{
  public static DataDomainInitializer&lt;T&gt; Init&lt;T&gt;(
      this DataDomain dd, params object[] parameters)
  {
    return new DataDomainInitializer&lt;T&gt;(dd.New&lt;T&gt;(parameters));
  }
}

public class DataDomainInitializer&lt;T&gt;
{
  private readonly T target;
  public DataDomainInitializer(T obj)
  {
    this.target = obj;
  }

  public T As(params Expression&lt;Func&lt;string, object&gt;&gt;[] expressions)
  {
    foreach (Expression&lt;Func&lt;string, object&gt;&gt; expression in expressions)
    {
      object value = GetValue(expression.Body);
      string key = expression.Parameters[0].Name;

      PropertyInfo property = typeof(T).GetProperty(key, 
        BindingFlags.Instance
        |BindingFlags.Public
        |BindingFlags.NonPublic);

      Type collectionType = GetCollectionType(property.PropertyType);
      if (collectionType != null)
      {
        CopyCollection(property, collectionType, value);
      }
      else
      {
        property.SetValue(target, value, null);
      }
    }
    return target;
  }

  private void CopyCollection(
      PropertyInfo property, Type collectionType, object collection)
  {
    object targetProperty = property.GetValue(target, null);

    MethodInfo addMethod = collectionType.GetMethod("Add");
    foreach (object enumValue in (IEnumerable)collection)
    {
      addMethod.Invoke(targetProperty, 
                       new object[] { enumValue });
    }
  }

  private static Type GetCollectionType(Type type)
  {
    foreach (Type @interface in type.GetInterfaces())
      if (@interface.IsGenericType &amp;&amp; 
          @interface.GetGenericTypeDefinition() 
            == typeof(ICollection&lt;&gt;))
          return @interface;

     return null;
  }

  private static object GetValue(Expression expression)
  {
     ConstantExpression constExpr = expression as ConstantExpression;
     if (constExpr != null)
       return constExpr.Value;
     return (Expression.Lambda&lt;Func&lt;object&gt;&gt;(expression).Compile())();
  }

}</pre>
        <p>
Posted by <a href="mailto:asz@tec_nospam_htalk.at">Attila</a>.
</p>
        <img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=8d2645c0-66a8-4064-b266-15a4d0464723" />
      </body>
      <title>Misusing c# lambda expressions</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,8d2645c0-66a8-4064-b266-15a4d0464723.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/0yX9ulUNApE/PermaLink,guid,8d2645c0-66a8-4064-b266-15a4d0464723.aspx</link>
      <pubDate>Tue, 05 Feb 2008 12:31:19 GMT</pubDate>
      <description>&lt;p&gt;
No, this article does not nag about some code I've seen that misuses new features.
This is how I did it - on purpose.
&lt;/p&gt;
&lt;p&gt;
I've always disliked the way I usually set up data in the database for testing: recreate
the database, create the domain objects, setting all the necessary properties, commit
the context. Take this code for example: 
&lt;/p&gt;
&lt;pre class="sourceCode"&gt;DataDomainSchema schema = DataDomainSchema.LoadFrom(&amp;quot;SomeMappingFile&amp;quot;);
schema.CreateDbSchema(connStr);

DataDomain dd = new DataDomain(schema, connStr);

using (Context.Push(ShortRunningTransactionContext.Create()))
{
  Customer tt = dd.New&amp;lt;Customer&amp;gt;();
  tt.Name = &amp;quot;TechTalk&amp;quot;;

  RootProject tt_hk = dd.New&amp;lt;RootProject&amp;gt;();
  tt_hk.Name = &amp;quot;Housekeeping&amp;quot;;

  ChildProject tt_hk_hol = dd.New&amp;lt;ChildProject&amp;gt;();
  tt_hk_hol.Name = &amp;quot;Holiday&amp;quot;;
  tt_hk.ChildProjects.Add(tt_hk_hol);

  ChildProject tt_hk_ill = dd.New&amp;lt;ChildProject&amp;gt;();
  tt_hk_ill.Name = &amp;quot;Illness&amp;quot;;

  tt_hk.ChildProjects.Add(tt_hk_ill);

  tt.RootProjects.Add(tt_hk);

  RootProject tt_g = dd.New&amp;lt;RootProject&amp;gt;();
  tt_g.Name = &amp;quot;Genome&amp;quot;;

  ChildProject tt_g_dev = dd.New&amp;lt;ChildProject&amp;gt;();
  tt_g_dev.Name = &amp;quot;Development&amp;quot;;
  tt_g.ChildProjects.Add(tt_g_dev);

  ChildProject tt_g_mnt = dd.New&amp;lt;ChildProject&amp;gt;();
  tt_g_mnt.Name = &amp;quot;Maintenance&amp;quot;;
  tt_g.ChildProjects.Add(tt_g_mnt);
  tt.RootProjects.Add(tt_g);

  Context.CommitCurrent();
}&lt;/pre&gt;
&lt;p&gt;
What I dislike in this is the 'setting all the necessary properties' part. Part of
it is that it's hard to follow the hierarchy of the objects. 
&lt;/p&gt;
&lt;p&gt;
The other is that I'm lazy. 
&lt;/p&gt;
&lt;p&gt;
Even if I'm typing with considerable speed - and keep pressing ctrl+(alt)+space and
let ReSharper do the rest - I still hate it for its repetitiousness. I always wanted
to have something like &lt;a href="http://rails.rubyonrails.com/classes/Fixtures.html"&gt;ActiveRecord's
Fixtures&lt;/a&gt; in Rails - but I never had the time to implement it. Yeah, typical excuse,
and that's how we usually &lt;i&gt;lose&lt;/i&gt; development time even in the short run, &lt;b&gt;&lt;u&gt;so&lt;/u&gt;&lt;/b&gt; I
know I'll have do it the next time I need to create test data.
&lt;/p&gt;
&lt;p&gt;
Sure, I could always create builder methods for every type to handle, passing in the
property values and collections etc, but even &lt;i&gt;creating&lt;/i&gt; those is yet another
repetitious task. I always longed for some more 'elegant' write-once-use-everywhere
kind of framework. So when I read &lt;a href="http://blog.bittercoder.com/PermaLink,guid,d1831805-dbf7-4b74-a6fd-2e9ed437c3d9.aspx"&gt;this
post&lt;/a&gt;, I thought, maybe I can get away with writing a simple, but usable enough,
initializer helper extension. Here's the resulting initializing code:
&lt;/p&gt;
&lt;pre class="sourceCode"&gt;...

using (Context.Push(ShortRunningTransactionContext.Create()))
{
  dd.Init&amp;lt;Customer&amp;gt;().As(
     Name =&amp;gt; &amp;quot;TechTalk&amp;quot;,
     RootProjects =&amp;gt; new Project[] {
       dd.Init&amp;lt;RootProject&amp;gt;().As(
         Name =&amp;gt; &amp;quot;Housekeeping&amp;quot;, 
         ChildProjects =&amp;gt; new Project[] {
           dd.Init&amp;lt;ChildProject&amp;gt;().As(Name =&amp;gt; &amp;quot;Holiday&amp;quot;),
           dd.Init&amp;lt;ChildProject&amp;gt;().As(Name =&amp;gt; &amp;quot;Illness&amp;quot;)
         }),
       dd.Init&amp;lt;RootProject&amp;gt;().As(
         Name =&amp;gt; &amp;quot;Genome&amp;quot;, 
         ChildProjects =&amp;gt; new Project[] {
           dd.Init&amp;lt;ChildProject&amp;gt;().As(Name =&amp;gt; &amp;quot;Development&amp;quot;),
           dd.Init&amp;lt;ChildProject&amp;gt;().As(Name =&amp;gt; &amp;quot;Maintenance&amp;quot;)
         })
       });

  Context.CommitCurrent();
}&lt;/pre&gt;
&lt;p&gt;
Prettier to the eye - but unfortunately, it's still not practical enough. For one
thing, it&amp;#8217;s easy to represent a tree this way, but it still doesn't offer a
solution for many-to-many relations. That's a lesser concern though, and I have ideas
for overcoming this (but haven&amp;#8217;t done it so far due to lack of time, again).
A greater problem is that it's not type safe: the parameter names of the lambdas (Name,
RootProjects, ChildProjects) are just that - names, aliases; they are not checked
during compile time. Even as a dynamic typed language advocate, I don't like too much
dynamic behavior in statically type languages - that usually results in little gain
if any, while losing their advantages, even 'developer-side' ones, like refactoring
or intellisense support.
&lt;/p&gt;
&lt;p&gt;
So, no conclusions there - I don't know which way I prefer yet. It seems that I &lt;i&gt;really&lt;/i&gt; will
have to go on and write some xml-file based initialization library (which will share
some of the abovementioned problems of the non-static languages, of course, but renaming
those properties in the config by hand which you just modified in the code at least &lt;i&gt;feels&lt;/i&gt; a
bit more normal).
&lt;/p&gt;
&lt;p&gt;
Still, if you're interested, here's the extension for doing the job:
&lt;/p&gt;
&lt;pre class="sourceCode"&gt;public static class DataDomainInitializerExtension

{
  public static DataDomainInitializer&amp;lt;T&amp;gt; Init&amp;lt;T&amp;gt;(
      this DataDomain dd, params object[] parameters)
  {
    return new DataDomainInitializer&amp;lt;T&amp;gt;(dd.New&amp;lt;T&amp;gt;(parameters));
  }
}

public class DataDomainInitializer&amp;lt;T&amp;gt;
{
  private readonly T target;
  public DataDomainInitializer(T obj)
  {
    this.target = obj;
  }

  public T As(params Expression&amp;lt;Func&amp;lt;string, object&amp;gt;&amp;gt;[] expressions)
  {
    foreach (Expression&amp;lt;Func&amp;lt;string, object&amp;gt;&amp;gt; expression in expressions)
    {
      object value = GetValue(expression.Body);
      string key = expression.Parameters[0].Name;

      PropertyInfo property = typeof(T).GetProperty(key, 
        BindingFlags.Instance
        |BindingFlags.Public
        |BindingFlags.NonPublic);

      Type collectionType = GetCollectionType(property.PropertyType);
      if (collectionType != null)
      {
        CopyCollection(property, collectionType, value);
      }
      else
      {
        property.SetValue(target, value, null);
      }
    }
    return target;
  }

  private void CopyCollection(
      PropertyInfo property, Type collectionType, object collection)
  {
    object targetProperty = property.GetValue(target, null);

    MethodInfo addMethod = collectionType.GetMethod(&amp;quot;Add&amp;quot;);
    foreach (object enumValue in (IEnumerable)collection)
    {
      addMethod.Invoke(targetProperty, 
                       new object[] { enumValue });
    }
  }

  private static Type GetCollectionType(Type type)
  {
    foreach (Type @interface in type.GetInterfaces())
      if (@interface.IsGenericType &amp;amp;&amp;amp; 
          @interface.GetGenericTypeDefinition() 
            == typeof(ICollection&amp;lt;&amp;gt;))
          return @interface;

     return null;
  }

  private static object GetValue(Expression expression)
  {
     ConstantExpression constExpr = expression as ConstantExpression;
     if (constExpr != null)
       return constExpr.Value;
     return (Expression.Lambda&amp;lt;Func&amp;lt;object&amp;gt;&amp;gt;(expression).Compile())();
  }

}&lt;/pre&gt;
&lt;p&gt;
Posted by &lt;a href="mailto:asz@tec_nospam_htalk.at"&gt;Attila&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=8d2645c0-66a8-4064-b266-15a4d0464723" /&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,8d2645c0-66a8-4064-b266-15a4d0464723.aspx</comments>
      <category>Genome</category>
      <category>Linq</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,8d2645c0-66a8-4064-b266-15a4d0464723.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=8e46822f-c3f5-4eca-b8ec-0040eceda566</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,8e46822f-c3f5-4eca-b8ec-0040eceda566.aspx</pingback:target>
      <dc:creator>Christian Hassa</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,8e46822f-c3f5-4eca-b8ec-0040eceda566.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=8e46822f-c3f5-4eca-b8ec-0040eceda566</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
With Genome, you can map standard 1:n and n:m collections for foreign-key/association
table database patterns out of the box by using Collection&lt;T&gt; and &lt;OneToManyCollection/&gt;
or &lt;ManyToManyCollection/&gt;.
</p>
        <p>
Compared to arbitrary relationships, which can also be mapped with Genome by using
Set&lt;T&gt; and a query, Collection&lt;T&gt; offers the following additional functionality: 
</p>
        <ul>
          <li>
Elements can be explicitly added and removed from the collection. 
</li>
          <li>
The collection is fully loaded into memory and kept consistent with in-memory object
graph modifications. 
</li>
          <li>
For n:m collections, Genome can fully hide the association class (mapping the database
association table) from the domain model if required.</li>
        </ul>
        <p>
        </p>
        <p>
However, for n:m collections, where the association class is annotated with additional
values (besides the foreign keys), the standard Collection&lt;T&gt; mapping does not
fit.
</p>
        <p>
To provide better support for those mapping scenarios, I have created a Dictionary-like
implementation for annotated many-to-many associations, where we can build the functionality
on the existing collection support.
</p>
        <h4>Example
</h4>
        <p>
I will use a simple domain model to present the idea. Let’s say we have Departments
and Employees in our domain. An employee can work in multiple departments, and a department
can have more than one employee. This classic many-to-many association is annotated
with a job description. The job description is encapsulated in a struct called Job.
</p>
        <p>
So the logical view looks like this:
</p>
        <img class="contentImage" title="My Title" src="content/images/annot_nmrel_image001.png" border="0" />
        <p>
In the database, we represent this kind of association with an association class/table
as follows:
</p>
        <img class="contentImage" title="My Title" src="content/images/annot_nmrel_image002.png" border="0" />
        <p>
The task is to implement the Department.Employees property, which represents the annotated
n:m relation in a consistent way.
</p>
        <h4>Representing an annotated n:m relationshop in the domain model
</h4>
        <p>
In my opinion the best representation for Department.Employees is an IDictionary&lt;Employee,
Job&gt;. It is ideal because the employees must be unique within the collection, and
the annotation data can be accessed if you additionally specify an Employee (index
into the dictionary with that employee). Note that this representation is only possible
if the annotation can be represented with a single typ; however, you can encapsulate
the annotations with a struct or class to achieve this at any time. You can use the
&lt;EmbeddedStruct/&gt; mapping feature to map this struct on the EmployedAs class.
</p>
        <h4>Mapping the association table as a one-to-many collection
</h4>
        <p>
First we have to map the one-to-many collection (Department.EmployedAsCollection):
</p>
        <pre class="sourceCode">protected abstract Collection&lt;EmployedAs&gt; EmployedAsCollection { get; }
</pre>
        <br />
        <pre class="sourceCode">&lt;Member name="EmployedAsCollection"&gt;
  &lt;OneToManyCollection parentReference="Department"/&gt;
&lt;/Member&gt;
</pre>
        <h4>Wrapping the association table into an annotated association
</h4>
        <p>
We will wrap this collection with a dictionary implementation to represent the annotated
association. I have created a helper class AnnotatedManyToManyDictionary that carries
out all necessary transformations. This strongly typed helper needs 4 generic parameters,
as you have to specify the association class (TAssoc=EmployedAs), the class owning
the collection (TOwner=Department), the “other side” of the association (that is,
the key in the dictionary, TKey=Employee) and the annotation that is the value in
the dictionary (TValue=Job). Basically, you have to wrap the collection with this
helper:
</p>
        <pre class="sourceCode">public IDictionary&lt;Employee, Job&gt; Employees
{
  get 
  { 
    return new AnnotatedManyToManyDictionary&lt;EmployedAs, Department, Employee, Job&gt;
      (this, EmployedAsCollection, EmployedAsDepartmentEmployeeJobAccessor.Instance);
  }
}
</pre>
        <h4>Helper strategy implementation for getting and setting the keys and values of
an association item
</h4>
        <p>
The helper class manages the underlying one-to-many collection and the association
items to provide the required behavior. As you probably noticed in the constructor
call, it still needs a little bit of help. You have to pass a strategy that “knows”
how to get and set the key and value properties of the association item. In the current
example, the EmployedAsEmployeeJobAccessor strategy knows how to get and set the Employee
and Job properties on an EmployedAs object. Currently you have to write this piece
of code to make that work:
</p>
        <pre class="sourceCode">private class EmployedAsEmployeeJobAccessor : 
  IAnnotatedManyToManyDictionaryAssociationAccessor&lt;EmployedAs, Employee, Job&gt;
{
  public static readonly EmployedAsEmployeeJobAccessor Instance =
    new EmployedAsEmployeeJobAccessor();

  public Employee GetKey(EmployedAs assoc)
  {
    return assoc.Employee;
  }

  public void SetKey(EmployedAs assoc, Employee key)
  {
    assoc.Employee = key;
  }

  public Job GetValue(EmployedAs assoc)
  {
    return assoc.Job;
  }

  public void SetValue(EmployedAs assoc, Job value)
  {
    assoc.Job = value;
  }
}
</pre>
        <h4>Usage
</h4>
        <p>
Having done this, you can easily iterate through the employees in a department:
</p>
        <pre class="sourceCode">Department dep = GetSomeDepartment();
foreach(Employee e in dep.Employees.Key) { ... }
</pre>
        <p>
You can also iterate through the association elements to retrieve the associated employees
of a department along with their job:
</p>
        <pre class="sourceCode">foreach(KeyValuePair&lt;Employee,Job&gt; in d1.Employees) { ... }
</pre>
        <p>
The job of an employee now depends on the associated department. The indexer of the
employees collection takes an associated employee and looks up the job annotated to
association:
</p>
        <pre class="sourceCode">Employee emp = GetSomeEmployee();
Job assignedJob = dep.Employees[emp];
</pre>
        <p>
Similarly, the job of an employee can be set for a specific department association:
</p>
        <pre class="sourceCode">dep.Employees[emp] = assignedJob;
</pre>
        <p>
Finally, when associating an employee to a department, the job annotation has to be
specified as well:
</p>
        <pre class="sourceCode">dep.Employees.Add(emp, assignedJob);
</pre>
Removing just requires the key, without the annotation: <pre class="sourceCode">dep.Employees.Remove(emp);
</pre><h4>Limitations
</h4><p>
The first limitation is performance with larger collections.. The current implementation
uses a linear search for looking up the employee key in the collection, which can
cause a performance hit in larger collections when adding or removing items or getting
an item’s annotation (using the indexer). The reason for this is that I didn’t want
to replace Genome’s internal representation of 1:n collections with a dictionary implementation.
</p><p>
The second limitation is that you need to manually code the helper strategy for getting
and setting the annotation value in the association items.
</p><p>
Based on your feedback, we might implement this as a native mapping feature in an
upcoming Genome release, thus resolving both limitations described.
</p><h4>Sample code
</h4><p>
Please find the source code for the example described above attached to this article.
</p><table class="attachmentsTable" border="0"><tbody><tr><td><a href="content/codesamples/AnnotatedManyToManyAssociation.zip"><img class="iconImage" title="AnnotatedManyToManyAssociation.zip" src="content/images/unknown.gif" border="0" /><div class="caption">AnnotatedManyToManyAssociation.zip
</div></a></td></tr></tbody></table><p>
Posted by <a href="mailto:tz@tec_nospam_htalk.at">TZ</a>.
</p><img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=8e46822f-c3f5-4eca-b8ec-0040eceda566" /></body>
      <title>Annotated many-to-many associations</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,8e46822f-c3f5-4eca-b8ec-0040eceda566.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/njrTFM6-pWQ/PermaLink,guid,8e46822f-c3f5-4eca-b8ec-0040eceda566.aspx</link>
      <pubDate>Tue, 22 Jan 2008 15:41:14 GMT</pubDate>
      <description>&lt;p&gt;
With Genome, you can map standard 1:n and n:m collections for foreign-key/association
table database patterns out of the box by using Collection&amp;lt;T&amp;gt; and &amp;lt;OneToManyCollection/&amp;gt;
or &amp;lt;ManyToManyCollection/&amp;gt;.
&lt;/p&gt;
&lt;p&gt;
Compared to arbitrary relationships, which can also be mapped with Genome by using
Set&amp;lt;T&amp;gt; and a query, Collection&amp;lt;T&amp;gt; offers the following additional functionality: 
&lt;ul&gt;
&lt;li&gt;
Elements can be explicitly added and removed from the collection. 
&lt;li&gt;
The collection is fully loaded into memory and kept consistent with in-memory object
graph modifications. 
&lt;li&gt;
For n:m collections, Genome can fully hide the association class (mapping the database
association table) from the domain model if required.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
However, for n:m collections, where the association class is annotated with additional
values (besides the foreign keys), the standard Collection&amp;lt;T&amp;gt; mapping does not
fit.
&lt;/p&gt;
&lt;p&gt;
To provide better support for those mapping scenarios, I have created a Dictionary-like
implementation for annotated many-to-many associations, where we can build the functionality
on the existing collection support.
&lt;/p&gt;
&lt;h4&gt;Example
&lt;/h4&gt;
&lt;p&gt;
I will use a simple domain model to present the idea. Let’s say we have Departments
and Employees in our domain. An employee can work in multiple departments, and a department
can have more than one employee. This classic many-to-many association is annotated
with a job description. The job description is encapsulated in a struct called Job.
&lt;/p&gt;
&lt;p&gt;
So the logical view looks like this:
&lt;/p&gt;
&lt;img class=contentImage title="My Title" src="content/images/annot_nmrel_image001.png" border=0&gt; 
&lt;p&gt;
In the database, we represent this kind of association with an association class/table
as follows:
&lt;/p&gt;
&lt;img class=contentImage title="My Title" src="content/images/annot_nmrel_image002.png" border=0&gt; 
&lt;p&gt;
The task is to implement the Department.Employees property, which represents the annotated
n:m relation in a consistent way.
&lt;/p&gt;
&lt;h4&gt;Representing an annotated n:m relationshop in the domain model
&lt;/h4&gt;
&lt;p&gt;
In my opinion the best representation for Department.Employees is an IDictionary&amp;lt;Employee,
Job&amp;gt;. It is ideal because the employees must be unique within the collection, and
the annotation data can be accessed if you additionally specify an Employee (index
into the dictionary with that employee). Note that this representation is only possible
if the annotation can be represented with a single typ; however, you can encapsulate
the annotations with a struct or class to achieve this at any time. You can use the
&amp;lt;EmbeddedStruct/&amp;gt; mapping feature to map this struct on the EmployedAs class.
&lt;/p&gt;
&lt;h4&gt;Mapping the association table as a one-to-many collection
&lt;/h4&gt;
&lt;p&gt;
First we have to map the one-to-many collection (Department.EmployedAsCollection):
&lt;/p&gt;
&lt;pre class=sourceCode&gt;protected abstract Collection&amp;lt;EmployedAs&amp;gt; EmployedAsCollection { get; }
&lt;/pre&gt;
&lt;br&gt;
&lt;pre class=sourceCode&gt;&amp;lt;Member name="EmployedAsCollection"&amp;gt;
  &amp;lt;OneToManyCollection parentReference="Department"/&amp;gt;
&amp;lt;/Member&amp;gt;
&lt;/pre&gt;
&lt;h4&gt;Wrapping the association table into an annotated association
&lt;/h4&gt;
&lt;p&gt;
We will wrap this collection with a dictionary implementation to represent the annotated
association. I have created a helper class AnnotatedManyToManyDictionary that carries
out all necessary transformations. This strongly typed helper needs 4 generic parameters,
as you have to specify the association class (TAssoc=EmployedAs), the class owning
the collection (TOwner=Department), the “other side” of the association (that is,
the key in the dictionary, TKey=Employee) and the annotation that is the value in
the dictionary (TValue=Job). Basically, you have to wrap the collection with this
helper:
&lt;/p&gt;
&lt;pre class=sourceCode&gt;public IDictionary&amp;lt;Employee, Job&amp;gt; Employees
{
  get 
  { 
    return new AnnotatedManyToManyDictionary&amp;lt;EmployedAs, Department, Employee, Job&amp;gt;
      (this, EmployedAsCollection, EmployedAsDepartmentEmployeeJobAccessor.Instance);
  }
}
&lt;/pre&gt;
&lt;h4&gt;Helper strategy implementation for getting and setting the keys and values of
an association item
&lt;/h4&gt;
&lt;p&gt;
The helper class manages the underlying one-to-many collection and the association
items to provide the required behavior. As you probably noticed in the constructor
call, it still needs a little bit of help. You have to pass a strategy that “knows”
how to get and set the key and value properties of the association item. In the current
example, the EmployedAsEmployeeJobAccessor strategy knows how to get and set the Employee
and Job properties on an EmployedAs object. Currently you have to write this piece
of code to make that work:
&lt;/p&gt;
&lt;pre class=sourceCode&gt;private class EmployedAsEmployeeJobAccessor : 
  IAnnotatedManyToManyDictionaryAssociationAccessor&amp;lt;EmployedAs, Employee, Job&amp;gt;
{
  public static readonly EmployedAsEmployeeJobAccessor Instance =
    new EmployedAsEmployeeJobAccessor();

  public Employee GetKey(EmployedAs assoc)
  {
    return assoc.Employee;
  }

  public void SetKey(EmployedAs assoc, Employee key)
  {
    assoc.Employee = key;
  }

  public Job GetValue(EmployedAs assoc)
  {
    return assoc.Job;
  }

  public void SetValue(EmployedAs assoc, Job value)
  {
    assoc.Job = value;
  }
}
&lt;/pre&gt;
&lt;h4&gt;Usage
&lt;/h4&gt;
&lt;p&gt;
Having done this, you can easily iterate through the employees in a department:
&lt;/p&gt;
&lt;pre class=sourceCode&gt;Department dep = GetSomeDepartment();
foreach(Employee e in dep.Employees.Key) { ... }
&lt;/pre&gt;
&lt;p&gt;
You can also iterate through the association elements to retrieve the associated employees
of a department along with their job:
&lt;/p&gt;
&lt;pre class=sourceCode&gt;foreach(KeyValuePair&amp;lt;Employee,Job&amp;gt; in d1.Employees) { ... }
&lt;/pre&gt;
&lt;p&gt;
The job of an employee now depends on the associated department. The indexer of the
employees collection takes an associated employee and looks up the job annotated to
association:
&lt;/p&gt;
&lt;pre class=sourceCode&gt;Employee emp = GetSomeEmployee();
Job assignedJob = dep.Employees[emp];
&lt;/pre&gt;
&lt;p&gt;
Similarly, the job of an employee can be set for a specific department association:
&lt;/p&gt;
&lt;pre class=sourceCode&gt;dep.Employees[emp] = assignedJob;
&lt;/pre&gt;
&lt;p&gt;
Finally, when associating an employee to a department, the job annotation has to be
specified as well:
&lt;/p&gt;
&lt;pre class=sourceCode&gt;dep.Employees.Add(emp, assignedJob);
&lt;/pre&gt;
Removing just requires the key, without the annotation: &lt;pre class=sourceCode&gt;dep.Employees.Remove(emp);
&lt;/pre&gt;
&lt;h4&gt;Limitations
&lt;/h4&gt;
&lt;p&gt;
The first limitation is performance with larger collections.. The current implementation
uses a linear search for looking up the employee key in the collection, which can
cause a performance hit in larger collections when adding or removing items or getting
an item’s annotation (using the indexer). The reason for this is that I didn’t want
to replace Genome’s internal representation of 1:n collections with a dictionary implementation.
&lt;/p&gt;
&lt;p&gt;
The second limitation is that you need to manually code the helper strategy for getting
and setting the annotation value in the association items.
&lt;/p&gt;
&lt;p&gt;
Based on your feedback, we might implement this as a native mapping feature in an
upcoming Genome release, thus resolving both limitations described.
&lt;/p&gt;
&lt;h4&gt;Sample code
&lt;/h4&gt;
&lt;p&gt;
Please find the source code for the example described above attached to this article.
&lt;/p&gt;
&lt;table class=attachmentsTable border=0&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="content/codesamples/AnnotatedManyToManyAssociation.zip"&gt;&lt;img class=iconImage title=AnnotatedManyToManyAssociation.zip src="content/images/unknown.gif" border=0&gt; 
&lt;div class=caption&gt;AnnotatedManyToManyAssociation.zip
&lt;/div&gt;
&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
Posted by &lt;a href="mailto:tz@tec_nospam_htalk.at"&gt;TZ&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=8e46822f-c3f5-4eca-b8ec-0040eceda566" /&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,8e46822f-c3f5-4eca-b8ec-0040eceda566.aspx</comments>
      <category>Genome</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,8e46822f-c3f5-4eca-b8ec-0040eceda566.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=b9e3019d-0d68-4344-9c7a-407774323d0f</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,b9e3019d-0d68-4344-9c7a-407774323d0f.aspx</pingback:target>
      <dc:creator>Christian Hassa</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,b9e3019d-0d68-4344-9c7a-407774323d0f.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=b9e3019d-0d68-4344-9c7a-407774323d0f</wfw:commentRss>
      <title>WCF: dispose/close proxies without the using statement</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,b9e3019d-0d68-4344-9c7a-407774323d0f.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/LDbyEPDIVVQ/PermaLink,guid,b9e3019d-0d68-4344-9c7a-407774323d0f.aspx</link>
      <pubDate>Fri, 18 Jan 2008 21:31:47 GMT</pubDate>
      <description>The using statement can be a little bit dangerous at times ...&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=b9e3019d-0d68-4344-9c7a-407774323d0f"/&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,b9e3019d-0d68-4344-9c7a-407774323d0f.aspx</comments>
      <category>WCF</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,b9e3019d-0d68-4344-9c7a-407774323d0f.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=0ed1ee8b-fd71-4f40-85a3-e5245f9dbba3</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,0ed1ee8b-fd71-4f40-85a3-e5245f9dbba3.aspx</pingback:target>
      <dc:creator>Christian Hassa</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,0ed1ee8b-fd71-4f40-85a3-e5245f9dbba3.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=0ed1ee8b-fd71-4f40-85a3-e5245f9dbba3</wfw:commentRss>
      <title>Using VS2008 vs. TFS2005</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,0ed1ee8b-fd71-4f40-85a3-e5245f9dbba3.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/D19GHz4KEaI/PermaLink,guid,0ed1ee8b-fd71-4f40-85a3-e5245f9dbba3.aspx</link>
      <pubDate>Wed, 09 Jan 2008 15:23:00 GMT</pubDate>
      <description>If you are using Visual Studio 2008 for a project, but are still using an old TFS and an old build server (which is quite likely at the moment), you should prepare for at least some inconveniences.&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=0ed1ee8b-fd71-4f40-85a3-e5245f9dbba3"/&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,0ed1ee8b-fd71-4f40-85a3-e5245f9dbba3.aspx</comments>
      <category>TFS</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,0ed1ee8b-fd71-4f40-85a3-e5245f9dbba3.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=09674370-1501-4d54-b98b-c44ec5c82682</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,09674370-1501-4d54-b98b-c44ec5c82682.aspx</pingback:target>
      <dc:creator>Christian Hassa</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,09674370-1501-4d54-b98b-c44ec5c82682.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=09674370-1501-4d54-b98b-c44ec5c82682</wfw:commentRss>
      <title>Team Foundation Server (TFS) source control grievances and alternative approaches in Subversion (SVN)</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,09674370-1501-4d54-b98b-c44ec5c82682.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/hLPo3HmSE9o/PermaLink,guid,09674370-1501-4d54-b98b-c44ec5c82682.aspx</link>
      <pubDate>Fri, 04 Jan 2008 15:19:22 GMT</pubDate>
      <description>Genome has been developed with Team Foundation Server (TFS) for some time now, and it might be interesting to know in this context that TechTalk is a Visual Studio Inner Circle partner. TFS has proven to be a good source control system, but there are a few points that could do with a bit of improvement (particularly when compared to Subversion (SVN), with which I have extensive experience; that said, there are some features that both systems lack).&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=09674370-1501-4d54-b98b-c44ec5c82682"/&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,09674370-1501-4d54-b98b-c44ec5c82682.aspx</comments>
      <category>TFS</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,09674370-1501-4d54-b98b-c44ec5c82682.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=8f3c1f80-fe7b-4d39-b67a-ab0b85bc5086</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,8f3c1f80-fe7b-4d39-b67a-ab0b85bc5086.aspx</pingback:target>
      <dc:creator>Christian Hassa</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,8f3c1f80-fe7b-4d39-b67a-ab0b85bc5086.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=8f3c1f80-fe7b-4d39-b67a-ab0b85bc5086</wfw:commentRss>
      <title>Exhibiting at TechEd Developers 2007 in Barcelona</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,8f3c1f80-fe7b-4d39-b67a-ab0b85bc5086.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/6uDNmGIOlb8/PermaLink,guid,8f3c1f80-fe7b-4d39-b67a-ab0b85bc5086.aspx</link>
      <pubDate>Thu, 15 Nov 2007 19:02:27 GMT</pubDate>
      <description>As I am writing this, I am just heading home from TechEd, waiting at the Barcelona airport for my return flight to Vienna. It has been a busy time for the Genome team since September - unfortunately so busy that we couldn’t take time to blog about all the things that are going on. We weren't at TechEd only as attendees, but also exhibiting in the Visual Studio Partner area, with a total of 8 TechTalkers in Barcelona. To catch up with all the things that have happened since September, I’ll start with TechEd, while the memories are still fresh.&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=8f3c1f80-fe7b-4d39-b67a-ab0b85bc5086"/&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,8f3c1f80-fe7b-4d39-b67a-ab0b85bc5086.aspx</comments>
      <category>Genome</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,8f3c1f80-fe7b-4d39-b67a-ab0b85bc5086.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=e69a43f8-e29f-4b3d-aeee-26167af309a3</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,e69a43f8-e29f-4b3d-aeee-26167af309a3.aspx</pingback:target>
      <dc:creator>Elina Heinonen</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,e69a43f8-e29f-4b3d-aeee-26167af309a3.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=e69a43f8-e29f-4b3d-aeee-26167af309a3</wfw:commentRss>
      <title>Mapping views with Genome</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,e69a43f8-e29f-4b3d-aeee-26167af309a3.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/WZzBJ2sz9eU/PermaLink,guid,e69a43f8-e29f-4b3d-aeee-26167af309a3.aspx</link>
      <pubDate>Thu, 08 Nov 2007 15:23:06 GMT</pubDate>
      <description>Typically, Genome is used to map tables to their data domain objects. But what to do when you have to use a database that is not made for mapping objects and therefore is not in any normalization form etc.?&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=e69a43f8-e29f-4b3d-aeee-26167af309a3"/&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,e69a43f8-e29f-4b3d-aeee-26167af309a3.aspx</comments>
      <category>General</category>
      <category>Genome</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,e69a43f8-e29f-4b3d-aeee-26167af309a3.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=1ec43809-de94-406a-81b8-74054fee9372</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,1ec43809-de94-406a-81b8-74054fee9372.aspx</pingback:target>
      <dc:creator>Christian Hassa</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,1ec43809-de94-406a-81b8-74054fee9372.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=1ec43809-de94-406a-81b8-74054fee9372</wfw:commentRss>
      <slash:comments>5</slash:comments>
      <title>C# 3.0 compiler issue with extensions methods</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,1ec43809-de94-406a-81b8-74054fee9372.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/Fx43ueK7xJg/PermaLink,guid,1ec43809-de94-406a-81b8-74054fee9372.aspx</link>
      <pubDate>Tue, 18 Sep 2007 15:24:01 GMT</pubDate>
      <description>&lt;p&gt;
While documenting/testing Genome 3.3 I stumbled about this strange behaviour, which
seems to be a bug of the C# 3.0 beta 2 compiler. 
&lt;/p&gt;
&lt;p&gt;
I was trying to compile the following GROUP BY example with Genome: 
&lt;/p&gt;
&lt;pre class=sourceCode&gt;var ordersPerCountryPerYear1 = from o in Helper.DB.Extent&lt;ORDER&gt;
() group o by new { o.Customer.Address.Country, o.OrderDate.Value.Year } into g select
new { Country = g.Key.Country, Year = g.Key.Year, OrderCount = g.Count() }; 
&lt;/pre&gt;
&lt;p&gt;
And received the following error from the compiler: 
&lt;/p&gt;
&lt;p&gt;
&lt;i&gt;&lt;ANONYMOUSTYPE#1,NORTHWIND.ORDER&gt;&lt;ANONYMOUSTYPE#1,NORTHWIND.ORDER&gt;error CS1061:
'System.Linq.IGrouping' does not contain a definition for 'Count' and no extension
method 'Count' accepting a first argument of type 'System.Linq.IGrouping' could be
found (are you missing a using directive or an assembly reference?)&lt;/i&gt; 
&lt;/p&gt;
&lt;p&gt;
However, my team insisted that the extension method Count() is provided by Genome.
To find out, why the compiler does not find it, they asked me to call it directly
in Main(): 
&lt;/p&gt;
&lt;pre&gt;&lt;INT, int&gt;TechTalk.Genome.Extensions.Linq.InternalIGroupingExtensions.Count(null);
&lt;/pre&gt;
&lt;p&gt;
After inserting this call in my code, the program suddenly compiled (including the
statement, the C# compiler complained about previously). 
&lt;/p&gt;
&lt;p&gt;
We think this is a bug of the compiler. As a workaround I now have the following method
on one class in my project to satisfy the compiler :-) : 
&lt;/p&gt;
&lt;pre class=sourceCode&gt;&lt;INT, int&gt;static void ThisIsNeverCalled()
{
  TechTalk.Genome.Extensions.Linq.InternalIGroupingExtensions.Count(null);
}
&lt;/pre&gt;
&lt;p&gt;
Posted by &lt;a href="mailto:ch@tec_nospam_htalk.at"&gt;Chris&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Technorati Tags: &lt;a href="http://technorati.com/tag/linq" rel=tag&gt;linq&lt;/a&gt; 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=1ec43809-de94-406a-81b8-74054fee9372" /&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,1ec43809-de94-406a-81b8-74054fee9372.aspx</comments>
      <category>Linq</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,1ec43809-de94-406a-81b8-74054fee9372.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=d00a95e7-76e2-41df-b849-4f67da225a74</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,d00a95e7-76e2-41df-b849-4f67da225a74.aspx</pingback:target>
      <dc:creator>Christian Hassa</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,d00a95e7-76e2-41df-b849-4f67da225a74.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=d00a95e7-76e2-41df-b849-4f67da225a74</wfw:commentRss>
      <title>Unit testing with Genome</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,d00a95e7-76e2-41df-b849-4f67da225a74.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/P5XjfLSNukg/PermaLink,guid,d00a95e7-76e2-41df-b849-4f67da225a74.aspx</link>
      <pubDate>Sun, 16 Sep 2007 13:25:25 GMT</pubDate>
      <description>&lt;p&gt;There are a lot of discussions how to properly mock an O/RM to achieve unit testing.&lt;/p&gt;

&lt;p&gt;
In this article, I will describe how an application implemented with Genome can be tested by means of unit testing. By stealing (and also modifying) the &lt;a href="http://martinfowler.com/articles/mocksArentStubs.html"&gt;sample domain from Fowler&lt;/a&gt;, I’ll demonstrate this with a simple WebShop application. The use case that we are going to investigate is the ordering process itself.
&lt;/p&gt;
&lt;p&gt;
The sample code used is provided for download at the end of the article. You need Genome 3.3 (beta 1) to execute the sample.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=d00a95e7-76e2-41df-b849-4f67da225a74"/&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,d00a95e7-76e2-41df-b849-4f67da225a74.aspx</comments>
      <category>Genome</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,d00a95e7-76e2-41df-b849-4f67da225a74.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=2648217a-be1b-41ae-a218-a24c91b2bbe6</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,2648217a-be1b-41ae-a218-a24c91b2bbe6.aspx</pingback:target>
      <dc:creator>Christian Hassa</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,2648217a-be1b-41ae-a218-a24c91b2bbe6.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=2648217a-be1b-41ae-a218-a24c91b2bbe6</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">TheServerSide.Net has just published our <a href="http://www.theserverside.net/news/thread.tss?thread_id=46914">case
study</a> about <a href="http://www.datareturn.com/">DataReturn's</a> experiences
of using Genome to rebuild website for BMW USA. The site has quite critical performance
requiremens of up to 1 million sessions per day. 
<p>
Posted by <a href="mailto:ch@tec_nospam_htalk.at">Chris</a></p><p>
Technorati Tags: <a href="http://technorati.com/tag/object+relational" rel="tag">object
relational</a><img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=2648217a-be1b-41ae-a218-a24c91b2bbe6" /></p></body>
      <title>Case study on DataReturn using Genome to build BMW USA site</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,2648217a-be1b-41ae-a218-a24c91b2bbe6.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/TavLq-e5GFk/PermaLink,guid,2648217a-be1b-41ae-a218-a24c91b2bbe6.aspx</link>
      <pubDate>Sat, 15 Sep 2007 08:19:10 GMT</pubDate>
      <description>TheServerSide.Net has just published our &lt;a href="http://www.theserverside.net/news/thread.tss?thread_id=46914"&gt;case
study&lt;/a&gt; about &lt;a href="http://www.datareturn.com/"&gt;DataReturn's&lt;/a&gt; experiences
of using Genome to rebuild website for BMW USA&gt;. The site has quite critical performance
requiremens of up to 1 million sessions per day. 
&lt;p&gt;
Posted by &lt;a href="mailto:ch@tec_nospam_htalk.at"&gt;Chris&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Technorati Tags: &lt;a href="http://technorati.com/tag/object+relational" rel=tag&gt;object
relational&lt;/a&gt; &lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=2648217a-be1b-41ae-a218-a24c91b2bbe6" /&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,2648217a-be1b-41ae-a218-a24c91b2bbe6.aspx</comments>
      <category>Genome</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,2648217a-be1b-41ae-a218-a24c91b2bbe6.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=b09e503a-324e-4403-bdb6-5006e215e9f7</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,b09e503a-324e-4403-bdb6-5006e215e9f7.aspx</pingback:target>
      <dc:creator>Christian Hassa</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,b09e503a-324e-4403-bdb6-5006e215e9f7.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=b09e503a-324e-4403-bdb6-5006e215e9f7</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Recently we received a question from a customer about how to express a sort criteria
based on a condition. As the sort expression in Genome is nothing else than an implicit
function (<i>lambda</i>) executed on the candidate element to return the value to
sort by, this can be quite easily achieved.
</p>
        <p>
As a simple example, let’s use the <i>Northwind database</i> again. A customer there
has a <code>Country</code> and a <code>Region</code> property. Imagine you want to
order all customers in the USA by <code>Region</code> and all the other customers
by <code>Country</code>. Additionally you want to have USA customers first, then the
others.
</p>
        <p>
        </p>
        <p>
A Genome set can be sorted using the <code>OrderBy()</code> method. It takes an implicit
function as a parameter, which is denoted using <code>[]</code> in OQL. The condition
can be expressed using the <code>?</code> operator, which is translated to a <code>CASE
WHEN</code> in SQL. Hence, the order function can be expressed like this:
</p>
        <p>
          <i>When the customer is located in the USA, then order by region; otherwise, order
by country:</i>
        </p>
        <p>
        </p>
        <pre class="sourceCode">
Country=="USA" ? Region : Country
</pre>
        <p>
To make sure customers located in the USA are listed first, I am prefixing the Region
with a space (I know this is a hack, but it will do for this example). Hence, the
final OQL looks like this:
</p>
        <p>
        </p>
        <pre class="sourceCode">
extentof(Customer).OrderBy( [ Country == "USA" ? " " + Region : Country])
</pre>
        <p>
which translates to the following SQL:
</p>
        <pre class="sourceCode">
SELECT … FROM Customers
  ORDER BY
    CASE WHEN (Country="USA")
       THEN (" " + Region)
       ELSE (Country)
    END ASC
</pre>
        <p>
Posted by <a href="mailto:ch@tec_nospam_htalk.at">Chris</a></p>
        <p>
Technorati Tags: <a href="http://technorati.com/tag/object+relational" rel="tag">object
relational</a>, <a href="http://technorati.com/tag/getting+started" rel="tag">getting
started</a></p>
        <img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=b09e503a-324e-4403-bdb6-5006e215e9f7" />
      </body>
      <title>Conditional sorting in OQL</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,b09e503a-324e-4403-bdb6-5006e215e9f7.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/zLL1L7FMHrQ/PermaLink,guid,b09e503a-324e-4403-bdb6-5006e215e9f7.aspx</link>
      <pubDate>Tue, 10 Jul 2007 19:00:41 GMT</pubDate>
      <description>&lt;p&gt;
Recently we received a question from a customer about how to express a sort criteria
based on a condition. As the sort expression in Genome is nothing else than an implicit
function (&lt;i&gt;lambda&lt;/i&gt;) executed on the candidate element to return the value to
sort by, this can be quite easily achieved.
&lt;/p&gt;
&lt;p&gt;
As a simple example, let’s use the &lt;i&gt;Northwind database&lt;/i&gt; again. A customer there
has a &lt;code&gt;Country&lt;/code&gt; and a &lt;code&gt;Region&lt;/code&gt; property. Imagine you want to
order all customers in the USA by &lt;code&gt;Region&lt;/code&gt; and all the other customers
by &lt;code&gt;Country&lt;/code&gt;. Additionally you want to have USA customers first, then the
others.&lt;p&gt;
&lt;p&gt;
A Genome set can be sorted using the &lt;code&gt;OrderBy()&lt;/code&gt; method. It takes an implicit
function as a parameter, which is denoted using &lt;code&gt;[]&lt;/code&gt; in OQL. The condition
can be expressed using the &lt;code&gt;?&lt;/code&gt; operator, which is translated to a &lt;code&gt;CASE
WHEN&lt;/code&gt; in SQL. Hence, the order function can be expressed like this:
&lt;/p&gt;
&lt;p&gt;
&lt;i&gt;When the customer is located in the USA, then order by region; otherwise, order
by country:&lt;/i&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;pre class=sourceCode&gt;
Country==&amp;quot;USA&amp;quot; ? Region : Country
&lt;/pre&gt;
&gt;
&lt;p&gt;
To make sure customers located in the USA are listed first, I am prefixing the Region
with a space (I know this is a hack, but it will do for this example). Hence, the
final OQL looks like this:
&lt;/p&gt;
&lt;p&gt;
&lt;pre class=sourceCode&gt;
extentof(Customer).OrderBy( [ Country == &amp;quot;USA&amp;quot; ? &amp;quot; &amp;quot; + Region : Country])
&lt;/pre&gt;
&gt;
&lt;p&gt;
which translates to the following SQL:
&lt;/p&gt;
&lt;pre class=sourceCode&gt;
SELECT … FROM Customers
  ORDER BY
    CASE WHEN (Country=&amp;quot;USA&amp;quot;)
       THEN (&amp;quot; &amp;quot; + Region)
       ELSE (Country)
    END ASC
&lt;/pre&gt;
&gt;
&lt;p&gt;
Posted by &lt;a href="mailto:ch@tec_nospam_htalk.at"&gt;Chris&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Technorati Tags: &lt;a href="http://technorati.com/tag/object+relational" rel="tag"&gt;object
relational&lt;/a&gt;, &lt;a href="http://technorati.com/tag/getting+started" rel="tag"&gt;getting
started&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=b09e503a-324e-4403-bdb6-5006e215e9f7" /&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,b09e503a-324e-4403-bdb6-5006e215e9f7.aspx</comments>
      <category>Genome</category>
      <category>OQL</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,b09e503a-324e-4403-bdb6-5006e215e9f7.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=1879f666-941f-445c-991c-76e4c977bb7c</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,1879f666-941f-445c-991c-76e4c977bb7c.aspx</pingback:target>
      <dc:creator>Christian Hassa</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,1879f666-941f-445c-991c-76e4c977bb7c.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=1879f666-941f-445c-991c-76e4c977bb7c</wfw:commentRss>
      <title>Starting Genome OQL Query Analyzer in the development environment</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,1879f666-941f-445c-991c-76e4c977bb7c.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/hx7HlspOFiE/PermaLink,guid,1879f666-941f-445c-991c-76e4c977bb7c.aspx</link>
      <pubDate>Wed, 04 Jul 2007 11:47:14 GMT</pubDate>
      <description>The Genome OQL Query Analyzer (QA) is a very helpful tool when you are developing with Genome: it allows you to load a mapped business layer to execute any kind of OQL queries.
In this article, I demonstrate how the latest mapped business layer, along with its mapping, can be loaded by starting the Genome QA with a single click in Visual Studio’s solution explorer.&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=1879f666-941f-445c-991c-76e4c977bb7c"/&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,1879f666-941f-445c-991c-76e4c977bb7c.aspx</comments>
      <category>Genome</category>
      <category>OQL</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,1879f666-941f-445c-991c-76e4c977bb7c.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=0800b911-9eca-4edb-bc49-7c62a6df4483</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,0800b911-9eca-4edb-bc49-7c62a6df4483.aspx</pingback:target>
      <dc:creator>Dirk Rombauts</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,0800b911-9eca-4edb-bc49-7c62a6df4483.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=0800b911-9eca-4edb-bc49-7c62a6df4483</wfw:commentRss>
      <title>Genome in a Windows Forms Application</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,0800b911-9eca-4edb-bc49-7c62a6df4483.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/HS_4ka-XJq0/PermaLink,guid,0800b911-9eca-4edb-bc49-7c62a6df4483.aspx</link>
      <pubDate>Fri, 29 Jun 2007 08:59:29 GMT</pubDate>
      <description>&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
In my &lt;a href="http://blog.genom-e.com/PermaLink,guid,1873fd45-5f8c-4171-bd79-51f10cd57a58.aspx"&gt;last
post&lt;/a&gt;, I described how to use the Genome Web Application starter kit to rapidly
create a web application that uses Genome.&amp;nbsp; To prove that Genome is not just
for web applications, I will now show how to create a windows forms application with
Genome.&amp;nbsp; There's no wizard that will create forms automatically (yet?), so there
are a couple more manual steps.&amp;nbsp; As you will see, however, it's not too difficult.
&lt;/p&gt;
&lt;p&gt;
I open visual studio, and reuse the datadomain and mapping projects I created in the &lt;a href="http://blog.genom-e.com/PermaLink,guid,cffe20b9-5251-4d8b-91fb-8cfc38c2ebdd.aspx"&gt;first
post&lt;/a&gt; in this series.&amp;nbsp; Then I add a new Windows Application project, call
it WinForms and designate it as Start Project. I reference the datadomain and mapping
projects, and the System.Configuration assembly.&amp;nbsp; I also reference the TechTalk.Genome
assembly, which is located in C:\Program Files\TechTalk\Genome 3.2 Professional Edition
for .NET 2.0\Bin\TechTalk.Genome.dll on my pc. I rename the Form1 files to MainForm.
I add an App.config file, and paste the connection string from the web project that
I created in my last post.&amp;nbsp; I then add a bindingsource to the form, and call
it customersBindingSource.&amp;nbsp; I configure the bindingsource to use the Genome.DataDomain.Customer
class from the DataDomain assembly (1). I add a DataGridView control to the form,
dock it to fill the form, and have it use the customer bindingsource.&amp;nbsp; You can
choose which columns you want to display in the grid; not all of them are that interesting
to watch ;-)
&lt;/p&gt;
&lt;p&gt;
So far, we used standard Windows Forms development techniques, but we still need to
fill the datasource of our customer bindingsource.&amp;nbsp; This is where it gets more
interesting.&amp;nbsp; We need a bit of plumbing code, but fortunately, we can use that
most venerable of code reuse techniques: copy and paste.&amp;nbsp; I Open up the directory
where Genome is installed (C:\Program Files\TechTalk\Genome 3.2 Professional Edition
for .NET 2.0 on my pc).&amp;nbsp; I drill down to Samples -&amp;gt; CSharp -&amp;gt; QuickStart
-&amp;gt; Step3-&amp;gt; WinFormsClient.&amp;nbsp; I Copy the files ContextBoundForm.cs, ContextFactory.cs&amp;nbsp;
and Helper.cs to the directory of my WinForms project, and include them in the project.&amp;nbsp;
I open the files and change the namespaces to WinForms. In Helper.cs, I change the
name of the _schemaAssembly field to "01ReverseEngineering.Mapping" (which is the
name of the mapping assembly compiled by the mappings project from my first blog post
in this series.). I change the name of the connection string to "MyRole" (or whatever
you defined as the name of the connection string in your app.config file). Now I open
MainForm.cs in code view and make the class inherit from ContextBoundForm.
&lt;/p&gt;
&lt;p&gt;
This code won't compile yet. The reason being that there's a using directive TechTalk.Genome.Extensions.Windows.Forms
in ContextFactory.cs.&amp;nbsp; If you are familiar with the theory behind windows databinding,
you will know that&amp;nbsp; the IBindingList interface is essential when binding lists
of data to a datagrid or a listbox.&amp;nbsp; However, Genome's Set&amp;lt;T&amp;gt; (which is
what is returned by any Genome query) does not implement that interface.&amp;nbsp; The
Genome team provided a SetBindingList&amp;lt;T&amp;gt;, which is a wrapper around Set&amp;lt;T&amp;gt;
that implements IBindingList.&amp;nbsp; You can find the code for this class in C:\Program
Files\TechTalk\Genome 3.2 Professional Edition for .NET 2.0\Extensions\Windows.Forms\SetBindingList.cs.
I add this file to the WinForms project (you can add it either as a copy or as a link).
I compile to make sure that I have copied all code I need.
&lt;/p&gt;
&lt;p&gt;
What is all this plumbing code about? One of the central concepts in Genome is the
Context.&amp;nbsp; A idea of a Context in Genome is comparable to a connection to a database.&amp;nbsp;
There can be many connections to the same database, but you need at least one connection
in order to do something usefull on your database. The same is true for a Context.&amp;nbsp;
The Genome equivalent of a database is called DataDomain, by the way.&amp;nbsp; ContextBoundForm
inherits from System.Windows.Forms.Form and adds a propery and a couple of methods
for using a Context.&amp;nbsp; ContextFactory does exactly what its name suggests.
&lt;/p&gt;
&lt;p&gt;
Now at last we can populate the custerm binding source. I open MainForm.cs in design
view, and double-click on the Form's title bar to create a handler for the load event.
Thanks to all our plumbing code, I only need to write customersBindingSource.DataSource
= new SetBindingList&amp;lt;Customer&amp;gt;(Helper.DB.Extent&amp;lt;Customer&amp;gt;(Context)); -
after adding using directives for Genome.DataDomain and TechTalk.Genome.Extensions.Windows.Forms,
that is.&amp;nbsp; I hit F5 to debug and run the application.&amp;nbsp; If all goes well,
the main form loads and you will see the list of customers in the data grid.&amp;nbsp;
In my case, not all went well at first and I had to make sure that my windows user
account had appropriate permissions on the Northwind database.&amp;nbsp; The result looks
something like this:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.genom-e.com/content/binary/Form1.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
That's it for today.&amp;nbsp; This post turned out to be way longer than I anticipated,
so I will save up the Orders and OrderDetails part and the editing part for the next
post.
&lt;/p&gt;
&lt;p&gt;
(1): If you have never worked with bindingsources in a windows forms application (and
even if you have), I can highly recommend &lt;a href="http://www.softinsight.com/bnoyes/"&gt;Brian
Noyes&lt;/a&gt;'s book &lt;a href="http://www.amazon.com/Data-Binding-Windows-Forms-2-0/dp/032126892X/ref=sr_11_1/105-5257729-0325244?ie=UTF8&amp;amp;qid=1182409191&amp;amp;sr=11-1"&gt;Data
Binding with Windows Forms 2.0 - Programming Smart Client Data Applications with .NET&lt;/a&gt;:
it's full of information about working with data binding in Windows Forms, and is
an enjoyable read.&amp;nbsp; If you are interested in the inner workings of data binding,
be sure to check out chapter 7, Understanding Data-Binding Interfaces.
&lt;/p&gt;
&lt;p&gt;
Posted by &lt;a href="mailto:dr@tec_nospam_htalk.at"&gt;Dirk&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Technorati Tags: &lt;a href="http://technorati.com/tag/object+relational" rel=”tag”&gt;object
relational&lt;/a&gt;, &lt;a href="http://technorati.com/tag/getting+started" rel=”tag”&gt;getting
started&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=0800b911-9eca-4edb-bc49-7c62a6df4483" /&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,0800b911-9eca-4edb-bc49-7c62a6df4483.aspx</comments>
      <category>General</category>
      <category>Genome</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,0800b911-9eca-4edb-bc49-7c62a6df4483.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=5f52e581-5257-4060-a4f4-204db5608a29</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,5f52e581-5257-4060-a4f4-204db5608a29.aspx</pingback:target>
      <dc:creator>Christian Hassa</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,5f52e581-5257-4060-a4f4-204db5608a29.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=5f52e581-5257-4060-a4f4-204db5608a29</wfw:commentRss>
      <title>O/RM challenge</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,5f52e581-5257-4060-a4f4-204db5608a29.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/iAv9bsQbWlY/PermaLink,guid,5f52e581-5257-4060-a4f4-204db5608a29.aspx</link>
      <pubDate>Thu, 28 Jun 2007 13:17:52 GMT</pubDate>
      <description>&lt;p&gt;
Mats Helander, whom I have already had the pleasure to meet personally several times,
wrote about &lt;a href="http://www.matshelander.com/wordpress/?p=55"&gt;an O/RM challenge&lt;/a&gt; in
his blog.
&lt;/p&gt;
&lt;p&gt;
While it is always fun to participate in challenges, I want to criticize the problem
Mats describes first, before I show how you can solve it with Genome.
&lt;/p&gt;
&lt;p&gt;
The challenge only concerns how efficiently an O/RM can read up a set of whole tables
from the database. This does not make sense for two reasons:
&lt;/p&gt;
&lt;p&gt;
&lt;ol&gt;
&lt;li&gt;
Usually, you don’t want to load up all the data from a database into memory (that’s
one of the reasons why you use a database). 
&lt;li&gt;
&lt;b&gt;If&lt;/b&gt; you have special cases, where you cache whole tables from a database (e.g.
some lookup data), caching takes place very seldom (e.g. once a day) and thus the
efficiency of loading up the data is not of such a big importance. 
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Mats expresses the challenge in such a way that he demands that the O/RM may not join
the related objects when loading from the database to find out about their relationships.
Instead, the O/RM should load up all objects at once, and “discover” the relations
between the objects afterwards on its own (without using the JOIN from the database).
This results in three SELECT statements (&lt;code&gt;SELECT * FROM Customers; SELECT * FROM
Orders; SELECT * FROM OrderLines&lt;/code&gt;). 
&lt;/p&gt;
&lt;p&gt;
An O/RM usually maintains only an identity map to cache object lookup queries. This
helps object references mapped through foreign key fields in the database to be followed
without extra database roundtrips (given that the related objects are already loaded
into memory). This means that following an &lt;code&gt;Order&lt;/code&gt; to its related &lt;code&gt;Customer&lt;/code&gt; works
in memory, if all data is loaded up. To discover the Orders belonging to the Customer,
however, the O/RM needs to perform a lookup query. 
&lt;/p&gt;
&lt;p&gt;
Some O/RMs, including Genome, allow collections to be preloaded in order to avoid
unnecessary roundtrips when traversing object graphs deeply. So you can tell the O/RM
to preload all the Orders of the Customers retrieved, and to preload all the OrderLines
of the Orders retrieved. In this case, the O/RM builds a map for relating the objects
in memory while loading up the data.
&lt;/p&gt;
&lt;p&gt;
Usually you only want to load up the related children of the parent table. It doesn’t
make sense to load up all orders from the database only to fulfill the orders of three
specific customers. To ensure this, an O/RM typically JOINs the related data to the
filtered parent table.
&lt;/p&gt;
&lt;p&gt;
Not filtering the parent table is a very special case. Introducing an optimisation
for this case is possible, but would make no sense (for the initial reasoning above).
Besides that, I wonder how large the loaded table has to be in order for that additional
JOIN to make a significant difference, giving the whole performance optimisation sense
at all. I guess in those cases, it is out of the question to cache the results in
memory anyway, which is the premise of the scenario. Another drawback of this optimisation
I want to point out is that it can turn out to be less efficient very quickly when
the parent reference is nullable, as unnecessary data is loaded up again.
&lt;/p&gt;
&lt;p&gt;
Still, this is a challenge and a lot of people interested in O/RM read it; so, let’s
solve it with Genome.
&lt;/p&gt;
&lt;p&gt;
Genome provides two infrastructures for retrieving and caching relations: collections
and indexing.
&lt;/p&gt;
&lt;p&gt;
The collection infrastructure provides rich support for handling specialised relation
types such as 1:n and n:m relations. Usually, I would recommend using Genome’s collection
mapping feature to support Mats’ scenario, except that Genome uses a JOIN to limit
the related objects loaded up from the database.
&lt;/p&gt;
&lt;p&gt;
Indexing is a Genome infrastructure that automatically detects even complex relationships,
based on the loaded data. It is more complex to configure, use and maintain, but it
can support Mats’ exotic scenario. Having mapped the business layer with Genome, the
following three lines of code will do the trick:
&lt;/p&gt;
&lt;p&gt;
&lt;pre class=sourceCode&gt;using (Context.Push(LocalContext.Create()))
{
    IndexManager.FillIndex(Context.Current, dd.Extent&amp;lt;OrderDetail&amp;gt;(), 
                           IndexManager.GetIndex(dd.Schema, typeof(OrderDetail), "IdxOrder"));

    IndexManager.FillIndex(Context.Current, dd.Extent&amp;lt;Order&amp;gt;(),
                           IndexManager.GetIndex(dd.Schema, typeof(Order), "IdxCustomer"));

    Set&amp;lt;Customer&amp;gt; customers = dd.Extent&amp;lt;Customer&amp;gt;().ToArray();

   Dump(customers);

}
&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Inside the using block, the first two lines of code load up all OrderDetails and all
Orders. Additionally, they saturate the indexes for the relationships &lt;code&gt;Order-&amp;gt;OrderDetail&lt;/code&gt; and &lt;code&gt;Customer-&amp;gt;Order&lt;/code&gt;.
The third line of code loads up all customers. When &lt;code&gt;Dump(customers)&lt;/code&gt; traverses
through the object graph, all relationships are served from memory.
&lt;/p&gt;
&lt;p&gt;
Note that this feature is not limited to simple 1:n and n:m relationships. It works
for more complex relationships as well, such as retrieving &lt;i&gt;pending orders&lt;/i&gt; of
a customer etc.
&lt;/p&gt;
&lt;p&gt;
Posted by &lt;a href="mailto:ch@tec_nospam_htalk.at"&gt;Chris&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Technorati Tags: &lt;a href="http://technorati.com/tag/object+relational" rel=”tag”&gt;object
relational&lt;/a&gt;, &lt;a href="http://technorati.com/tag/challenge" rel=”tag”&gt;challenge&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=5f52e581-5257-4060-a4f4-204db5608a29" /&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,5f52e581-5257-4060-a4f4-204db5608a29.aspx</comments>
      <category>Genome</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,5f52e581-5257-4060-a4f4-204db5608a29.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=6f2ebfd2-5aa4-411a-b228-9338118baba6</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,6f2ebfd2-5aa4-411a-b228-9338118baba6.aspx</pingback:target>
      <dc:creator>Christian Hassa</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,6f2ebfd2-5aa4-411a-b228-9338118baba6.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=6f2ebfd2-5aa4-411a-b228-9338118baba6</wfw:commentRss>
      <title>Using ToObject() in OQL</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,6f2ebfd2-5aa4-411a-b228-9338118baba6.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/bwIE8AiRsqQ/PermaLink,guid,6f2ebfd2-5aa4-411a-b228-9338118baba6.aspx</link>
      <pubDate>Tue, 26 Jun 2007 08:46:19 GMT</pubDate>
      <description>&lt;p&gt;
In Genome, you can use &lt;code&gt;ToObject()&lt;/code&gt; to return a single object from a query
that has zero or one result element. The Genome documentation gives the following
explanation about the restriction on the number of result elements:
&lt;/p&gt;
&lt;p&gt;
&lt;blockquote&gt;The method should not be called for sets that may contain more than one
element. Calling the method for these kinds of sets results in different behaviours
based on the database platform and the calling context. If you need to retrieve the
first element of a set, the combination of &lt;code&gt;Set&lt;T&gt;
.GetRange
&lt;/code&gt; and &lt;code&gt;Set&lt;T&gt;
.ToObject
&lt;/code&gt; has to be used, as in the following example.&lt;/blockquote&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
But when can you be sure that a query returns only zero or one element? And what happens
if you do not follow that advice?
&lt;/p&gt;
&lt;p&gt;
A common case that would require using ToObject() is when you need to map an inverse
object reference of a 1:1 relationship in the domain model. 
&lt;/p&gt;
&lt;p&gt;
Imagine the following example, where a company car can be assigned to one or no employee:
In this case, the company car has an object reference to the employee it can be assigned
to, represented by a foreign key in the database. Vice-versa, the employee has an
object reference to the assigned company car, implemented through a lookup query that
returns the car that is being assigned to this employee:
&lt;/p&gt;
&lt;p&gt;
&lt;pre class=sourceCode&gt;public abstract class CompanyCar
{
	...
	public abstract Employee AssignedTo { get; set; }
	...
}&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;pre class=sourceCode&gt;&amp;lt;Type name="CompanyCar"&amp;gt;
	...
	&amp;lt;Member name="AssignedTo"&amp;gt;&amp;lt;NearObjectReference/&amp;gt;&amp;lt;/Member&amp;gt;
&amp;lt;/Type&amp;gt;&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;pre class=sourceCode&gt;public abstract class Employee
{
	...
	public abstract CompanyCar AssignedCar { get; }
	...
}&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;pre class=sourceCode&gt;&amp;lt;Type name="Employee"&amp;gt;
	...
	&amp;lt;Member name="AssignedCar" Oql="extentof(CompanyCar)[ccar: ccar.AssignedTo==this].ToObject()" /&amp;gt;
	...
&amp;lt;/Type&amp;gt;&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Note the following details:
&lt;/p&gt;
&lt;p&gt;
&lt;ol&gt;
&lt;li&gt;
Employee.AssignedCar is readonly, while CompanyCar.AssignedTo is read/writeable. This
is logical, since Employee.AssignedCar is only mapped to a query, where you cannot
“set” the result. Of course, you can implement a more sophisticated property on Employee
which would allow the car to be set directly for an employee, but I leave this out
for simplicity’s sake. 
&lt;li&gt;
The lookup query mapped to Employee.AssignedCar retrieves a single car instance by
using ToObject(). This assumes that the lookup query returns only zero or one result
element, which is the point I wanted to discuss in this article.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Having mapped this, you can freely navigate from CompanyCar to Employee and vice-versa,
as shown below.
&lt;/p&gt;
&lt;p&gt;
Navigating from CompanyCar to Employee executes a lookup query for the foreign key
against the database:
&lt;/p&gt;
&lt;p&gt;
&lt;pre class=sourceCode&gt;SELECT ... FROM Employee WHERE Id = {CompanyCar.AssignedTo}&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Navigating from Employee to CompanyCar executes a lookup query for the primary key
of the Employee instance in the AssignedTo fields of the CompanyCar table:
&lt;/p&gt;
&lt;p&gt;
&lt;pre class=sourceCode&gt;SELECT TOP 1 ... FROM CompanyCar WHERE AssignedTo = {Employee.Id}&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
The beauty of this mapping is that the domain model’s user does not need to be aware
in which direction the relationship is mapped in the database. You can even build
more complex queries using the property . For example, finding all Employees that
have a CompanyCar assigned to them is easy in OQL:
&lt;/p&gt;
&lt;p&gt;
&lt;pre class=sourceCode&gt;extentof(Employee)[AssignedCar != null]&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
This translates to the following SQL:
&lt;/p&gt;
&lt;p&gt;
&lt;pre class=sourceCode&gt;SELECT ... FROM Employee
  LEFT OUTER JOIN CompanyCar ON CompanyCar.AssignedToId=Employee.Id
  WHERE NOT CompanyCar.Id IS NULL&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
If you change the database schema to point the foreign key in the other direction,
the same OQL is translated to the following SQL:
&lt;/p&gt;
&lt;p&gt;
&lt;pre class=sourceCode&gt;SELECT ... FROM Employee WHERE NOT AssignedCar.Id IS NULL&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
The important point that I want to make is that ToObject() works fine as long as you
can be sure it will return only zero or one result. In my example, if there were more
than one car assigned to an employee, then the SQL query would return duplicate employee
entries for those employees with more than one car assigned:
&lt;/p&gt;
&lt;p&gt;
&lt;pre class=sourceCode&gt;SELECT ... FROM Employee 
  LEFT OUTER JOIN CompanyCar ON CompanyCar.AssignedToId=Employee.Id
  WHERE NOT CompanyCar.Id IS NULL&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
A wrong approach to fixing this problem is to use a distinct projection, eliminating
the duplicate employee entries from the result:
&lt;/p&gt;
&lt;p&gt;
&lt;pre class=sourceCode&gt; [this distinct]extentof(Employee)[AssignedCar != null]&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
This translates to:
&lt;/p&gt;
&lt;p&gt;
&lt;pre class=sourceCode&gt;SELECT DISTINCT ... FROM Employee 
  LEFT OUTER JOIN CompanyCar ON CompanyCar.AssignedToId=Employee.Id
  WHERE NOT CompanyCar.Id IS NULL&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
There are several reasons why using a distinct projection is not a good solution to
the problem in this case. First of all, you do not want to change the semantics of
your query in OQL, just to work around this problem. There might be many other places
where you run into similar problems which you would have to fix with additional projections
or other hacks one by one. Second, DISTINCT limits the query in some cases, e.g. you
cannot sort by a field not contained in the selector anymore when using DISTINCT.
&lt;/p&gt;
&lt;p&gt;
The right approach to solving this problem reflects the fact that there can be more
than one CompanyCar assigned to an employee in the mapping of the relationship. There
are two ways of doing this.
&lt;/p&gt;
&lt;p&gt;
The simplest is to tell Genome to expect more than one result in the lookup, and return
only the first. This can make sense if you want to return “any” of the assigned cars.
If you combine it with an order criterion that defines which cars to return first,
this can be even more meaningful. The following mapping would return the most expensive
car assigned to an employee:
&lt;/p&gt;
&lt;p&gt;
&lt;pre class=sourceCode&gt;&amp;lt;Type name="Employee"&amp;gt;
	...
	&amp;lt;Member name="AssignedCar" Oql="extentof(CompanyCar)[ccar: ccar.AssignedTo==this].OrderBy([Price descending]).GetRange(0,1).ToObject()" /&amp;gt;
	...
&amp;lt;/Type&amp;gt;&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt;.OrderBy([Price descending])&lt;/code&gt; ensures that the most expensive car is returned
first.
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt;GetRange(0,1)&lt;/code&gt; tells Genome to make sure only one result is returned.
Depending on how AssignedCar is used in another OQL, Genome shapes the resulting query
accordingly.
&lt;/p&gt;
&lt;p&gt;
After mapping AssignedCar as above, the original query
&lt;/p&gt;
&lt;p&gt;
&lt;pre class=sourceCode&gt;extentof(Employee)[AssignedCar != null]&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
is now translated to the following SQL:
&lt;/p&gt;
&lt;p&gt;
&lt;pre class=sourceCode&gt;SELECT ... FROM Employee
  WHERE NOT(
    SELECT TOP 1 FROM CompanyCar WHERE CompanyCar.AssignedToId = Employee.Id
    ORDER BY CompanyCar.Price DESC
  ) IS NULL&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Note that, because &lt;code&gt;GetRange(0,1)&lt;/code&gt; is used in the mapping of &lt;code&gt;Employee.AssignedCar&lt;/code&gt;,
Genome implements the same OQL to search for employees without a car, using a sub-query
instead of using LEFT OUTER JOIN.
&lt;/p&gt;
&lt;p&gt;
Depending on your business use case, you might choose to do more complex refactoring
of your business model to reflect that more than one car can be assigned to an employee.
For example, you could introduce an additional property to Employee that returns Set&lt;COMPANYCAR&gt;
with all assigned cars. You would still need to define how queries that retrieve only
a single instance of a car should work, no matter how many cars are assigned to an
employee.
&lt;/p&gt;
&lt;h4&gt;Summary
&lt;/h4&gt;
&lt;p&gt;
When using &lt;code&gt;ToObject()&lt;/code&gt; alone to retrieve a single element from a set,
make sure that the set can only contain zero or one element. Otherwise, you will end
up with unwanted side effects when building more complex queries based on this query.
&lt;/p&gt;
&lt;p&gt;
When you know a query can return more than one element, but you just want to fetch
the top element, use GetRange(0,1) in combination with ToObject(). For example, if
you want to retrieve the most expensive car from the car pool, use
&lt;/p&gt;
&lt;p&gt;
&lt;pre class=sourceCode&gt;extentof(CompanyCar).OrderBy([Price descending]).GetRange(0,1).ToObject()&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
It is also possible that your data is inconsistent; more than one CompanyCar may be
assigned to an Employee, although business rules forbid this. In this case, this is
a bug in your software which you should resolve otherwise (e.g. through proper business
rule checks or database constraints). Using &lt;code&gt;GetRange(0,1)&lt;/code&gt; does not really
help, as it does not represent the business intent you want to implement. 
&lt;/p&gt;
&lt;p&gt;
It may also be tempting to use &lt;code&gt;GetRange(0,1)&lt;/code&gt; “just to be sure”, but note
that this adds unnecessary performance overhead. For example, joining in a TOP query
is far more complex and slow than joining in the same without &lt;code&gt;GetRange(0,1)&lt;/code&gt;.
In fact, this is the reason why we have not included &lt;code&gt;GetRange(0,1)&lt;/code&gt; in &lt;code&gt;ToObject()&lt;/code&gt;. 
&lt;/p&gt;
&lt;p&gt;
Posted by &lt;a href="mailto:ch@tec_nospam_htalk.at"&gt;Chris&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Technorati Tags: &lt;a href="http://technorati.com/tag/object+relational" rel=”tag”&gt;object
relational&lt;/a&gt;, &lt;a href="http://technorati.com/tag/getting+started" rel=”tag”&gt;getting
started&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=6f2ebfd2-5aa4-411a-b228-9338118baba6" /&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,6f2ebfd2-5aa4-411a-b228-9338118baba6.aspx</comments>
      <category>Genome</category>
      <category>OQL</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,6f2ebfd2-5aa4-411a-b228-9338118baba6.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=1873fd45-5f8c-4171-bd79-51f10cd57a58</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,1873fd45-5f8c-4171-bd79-51f10cd57a58.aspx</pingback:target>
      <dc:creator>Dirk Rombauts</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,1873fd45-5f8c-4171-bd79-51f10cd57a58.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=1873fd45-5f8c-4171-bd79-51f10cd57a58</wfw:commentRss>
      <title>Using the Genome Web Application Wizard</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,1873fd45-5f8c-4171-bd79-51f10cd57a58.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/RJ_v84a81-A/PermaLink,guid,1873fd45-5f8c-4171-bd79-51f10cd57a58.aspx</link>
      <pubDate>Fri, 22 Jun 2007 08:50:56 GMT</pubDate>
      <description>&lt;p&gt;
In my previous installment, I wrote about using the Database Reverse Engineering Wizard
to create classes and mappings for an existing database.&amp;nbsp; In today's post, I
talk about using the Genome Web Application Wizard to create a simple, yet fully functional
ASP.NET Site to view and edit entries in your database.
&lt;/p&gt;
&lt;p&gt;
I'm basically continuing where I left off last time.&amp;nbsp; I have a Visual Studio
Solution with two projects: one with the DataDomain classes, and one with the mapping
files.&amp;nbsp; Now I add a new project using File -&amp;gt; Add -&amp;gt; New Project ...&amp;nbsp;
I select Visual C# (the Wizard seems to be a C#-only affair), and then Genome Web
Application.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.genom-e.com/content/binary/AddStarterKit.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
I gve the project a name, and click OK.&amp;nbsp; I click Next on the Wizard's Welcome
page, and come to the page where I select the DataDomain Schema (or Mapping) project,
and the Business Project.&amp;nbsp; The Wizard is smart enough to automatically detect
the appropriate projects in the solution.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.genom-e.com/content/binary/Wizard.jpg" border=0&gt; 
&lt;/p&gt;
&lt;p&gt;
Next once more, I enter the connection string again, click Finish and Finish again.&amp;nbsp;
I now have a third project in my solution, with appropriate references, CSS adapaters,
a default page, a master page and a couple of helper classes.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.genom-e.com/content/binary/SolutionExplorer1.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
At this point, I made the mistake of thinking that the wizard had malfunctioned because
there are no pages for my business objects.&amp;nbsp; There's only a default.aspx page,
and that one is empty.&amp;nbsp; One of my colleagues kindly explained to me that I need
to add those pages manually.&amp;nbsp; That way, I can specify exactly what such a page
should contain.
&lt;/p&gt;
&lt;p&gt;
So I right-click the web application project, point to Add and select New Item.&amp;nbsp;
There are two Genome-related items to choose from, the Genome Details Page and the
Genome List Page. I select Genome List Page and call it Orders.aspx.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.genom-e.com/content/binary/AddItem.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
I click on Add, and another part of the wizard appears.&amp;nbsp; I click Next to get
past the welcome screen, I choose my business object class (Order) and click next
again. A screen with several settings appears.&amp;nbsp; I leave the default values, except
that I enable in-place editing.&amp;nbsp; I click Finish twice and the wizards adds Orders.aspx
to the web application.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.genom-e.com/content/binary/SelectClass.jpg" border=0&gt; 
&lt;/p&gt;
&lt;p&gt;
I set&amp;nbsp;Orders.aspx&amp;nbsp;as the project's start page and hit F5.&amp;nbsp; A browser
window opens and I see a page with&amp;nbsp;filter options and the results of the search.&amp;nbsp;
Go ahead and play&amp;nbsp;around with the filter options.&amp;nbsp; The Edit and Delete links
are fully functional as well.&amp;nbsp; Play around with these as well.&amp;nbsp; Show Details
leads to an HTML 404 error however, since we haven't yet defined a details page for
the Order business entity.&amp;nbsp; I close the browser and return to Visual Studio.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.genom-e.com/content/binary/Form.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
I add another item to the web application, but this time I select a Genome Details
Page.&amp;nbsp; I click through the wizard, select Order for my business class and basically
accept all the default values.&amp;nbsp; The wizard adds an OrderDetails.aspx page to
the project. I hit F5 again, and the Orders.aspx page opens again.&amp;nbsp; I click on
Show Detail for one of the items, and this time OderDetails.aspx opens and shows the
details of the Order object.
&lt;/p&gt;
&lt;p&gt;
You can repeat this process for all business entities that you want to view and edit
in the web application.&amp;nbsp; Using the Genome Web Application wizard, you can quickly
generate a&amp;nbsp;small but fully functional web site for editing your business data.
&lt;/p&gt;
&lt;p&gt;
In the next installment, I will show how to create a Windows Forms application that
uses Genome.
&lt;/p&gt;
&lt;p&gt;
Posted by &lt;a href="mailto:dr@tec_nospam_htalk.at"&gt;Dirk&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Technorati Tags: &lt;a href="http://technorati.com/tag/object+relational" rel=”tag”&gt;object
relational&lt;/a&gt;, &lt;a href="http://technorati.com/tag/getting+started" rel=”tag”&gt;getting
started&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=1873fd45-5f8c-4171-bd79-51f10cd57a58" /&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,1873fd45-5f8c-4171-bd79-51f10cd57a58.aspx</comments>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,1873fd45-5f8c-4171-bd79-51f10cd57a58.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=cffe20b9-5251-4d8b-91fb-8cfc38c2ebdd</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,cffe20b9-5251-4d8b-91fb-8cfc38c2ebdd.aspx</pingback:target>
      <dc:creator>Dirk Rombauts</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,cffe20b9-5251-4d8b-91fb-8cfc38c2ebdd.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=cffe20b9-5251-4d8b-91fb-8cfc38c2ebdd</wfw:commentRss>
      <title>Reverse Engineering a Database with Genome</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,cffe20b9-5251-4d8b-91fb-8cfc38c2ebdd.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/0JHCWiSWSEY/PermaLink,guid,cffe20b9-5251-4d8b-91fb-8cfc38c2ebdd.aspx</link>
      <pubDate>Fri, 15 Jun 2007 09:16:50 GMT</pubDate>
      <description>&lt;p&gt;
Most software projects start with an existing database.&amp;nbsp; It's not often that
you get the chance to start from scratch and design the database the way you like
it.&amp;nbsp; Now, creating Genome mappings for an existing database is a tedious job,
but thankfully we have the Database Reverse Engineering Wizard for that.&amp;nbsp; So
let's start Visual Studio 2005, and create a new Database Reverse Engineering project.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="/content/binary/NewProject.jpg"&gt;
&lt;/p&gt;
&lt;p&gt;
Genome will start a wizard.&amp;nbsp; Connect to Northwind, select all tables, accept
the names for the projects or choose your own, change any options if you like (I opted
to have Genome create&amp;nbsp;default constructors)&amp;nbsp;and click finish.&amp;nbsp; Genome
will now generate two projects for you, one with classes for your domain model, and
one for the mappings of those classes to database tables.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="/content/binary/solutionexplorer.jpg"&gt;
&lt;/p&gt;
&lt;p&gt;
Let's have a look at some of the class file that the wizard generated for you. Open
the Order.cs (or Order.vb if you selected VB.NET as your language of choice).
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: #f1f1f1; COLOR: black; FONT-FAMILY: consolas"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; System;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; TechTalk.Genome;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; TechTalk.Genome.Mapping;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; System.ComponentModel;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;span style="COLOR: blue"&gt;namespace&lt;/span&gt; Genome.DataDomain
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
[&lt;span style="COLOR: #2b91af"&gt;TypeConverter&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: #2b91af"&gt;ExpandableObjectConverter&lt;/span&gt;))]
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Order&lt;/span&gt; : &lt;span style="COLOR: #2b91af"&gt;Persistent&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;11&lt;/span&gt;&amp;nbsp;&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; #region&lt;/span&gt; Primary Keys
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;12&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;13&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; OrderId
{ &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;14&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;15&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; Order()
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;16&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;17&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;18&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;19&lt;/span&gt;&amp;nbsp;&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;20&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;21&lt;/span&gt;&amp;nbsp;&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; #region&lt;/span&gt; Scalar Fields
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;22&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;23&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Nullable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;DateTime&lt;/span&gt;&amp;gt;
OrderDate { &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt;;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;24&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Nullable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;DateTime&lt;/span&gt;&amp;gt;
RequiredDate { &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt;;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;25&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Nullable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;DateTime&lt;/span&gt;&amp;gt;
ShippedDate { &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt;;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;26&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Nullable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;decimal&lt;/span&gt;&amp;gt;
Freight { &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt;;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;27&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; ShipName
{ &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt;; }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;28&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; ShipAddress
{ &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt;; }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;29&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; ShipCity
{ &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt;; }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;30&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; ShipRegion
{ &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt;; }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;31&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; ShipPostalCode
{ &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt;; }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;32&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; ShipCountry
{ &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt;; }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;33&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;34&lt;/span&gt;&amp;nbsp;&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;35&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;36&lt;/span&gt;&amp;nbsp;&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; #region&lt;/span&gt; Reference Fields
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;37&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;38&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Customer&lt;/span&gt; Customer
{ &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt;; }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;39&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Employee&lt;/span&gt; Employee
{ &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt;; }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;40&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Shipper&lt;/span&gt; ShipVia
{ &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt;; }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;41&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;42&lt;/span&gt;&amp;nbsp;&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;43&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;44&lt;/span&gt;&amp;nbsp;&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; #region&lt;/span&gt; One To Many Associations
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;45&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;46&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Collection&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;OrderDetail&lt;/span&gt;&amp;gt;
OrderDetails
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;47&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
{ 
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;48&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;49&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;50&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;51&lt;/span&gt;&amp;nbsp;&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;52&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;53&lt;/span&gt;&amp;nbsp;&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; #region&lt;/span&gt; Many To Many Associations
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;54&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;55&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Collection&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;Product&lt;/span&gt;&amp;gt;
Products
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;56&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
{ 
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;57&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;58&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;59&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;60&lt;/span&gt;&amp;nbsp;&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;61&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;62&lt;/span&gt;&amp;nbsp;}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
The file starts out with a couple of using declaration that refence the Genome namespaces.
The Order class is annotated with the TypeConverter attribute, which is useful to
display Genome objects in a property grid.&amp;nbsp; The first member we encounter is
a property for the primary key of the Order entity, in this case a simple integer.&amp;nbsp;
There's also the default constructor, which is protected because we are dealing with
an abstract class.&amp;nbsp;Then come a&amp;nbsp;number of simple properties, nothing exciting.&amp;nbsp;
After that it gets more interesting.
&lt;/p&gt;
&lt;p&gt;
The Orders table has several&amp;nbsp;foreign key contraints.&amp;nbsp; Those foreign keys
are represented by references to related objects.&amp;nbsp; For example, the foreign key
to the Employees table as mapped by a property of type Employee.&amp;nbsp;&amp;nbsp;We have
the other&amp;nbsp;direction as well: the OrderDetails table&amp;nbsp;has a foreign key to
the Orders table.&amp;nbsp;&amp;nbsp;This results in the Order class having a collection of
OrderDetail objects.&amp;nbsp; If you take a look at the OrderDetail class, you will find
it has a property of type Order for its side of the relation.
&lt;/p&gt;
&lt;p&gt;
Lastly we have an m-p relation&amp;nbsp;between&amp;nbsp;the Orders and the Products tables,
with the OrderDetails table as connection table.&amp;nbsp; Genome creates a collection
of Product objects in the Order class, and a collection of Order object in the Product
class.
&lt;/p&gt;
&lt;p&gt;
By this time, you are probably wondering why the classes and all those properties
are abstract. The reason becomes clear when we use Reflector to have a look at the
assembly compiled by Genome.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="/content/binary/solutionexplorer.jpg"&gt;
&lt;/p&gt;
&lt;p&gt;
For every class generated by the Database Reverse Engineering wizard, there are two
classes in this assembly: one in a namespace starting with GenomeContextBoundProxy
and one in a namespace starting with GenomeContextUnboundProxy.&amp;nbsp; The Genome runtime
will use one or the other depending on the Genome Context. The distinction between
the two kinds of proxies isn't that important, though. What is important is the fact
that Genome uses the proxy design pattern. This all happens behind the scenes however,
so as an application developer you will only deal directly with the abstract classes.
&lt;/p&gt;
&lt;p&gt;
In the next installment, I'll use the Genome starter kit to create a web application
that uses the two projects we just generated.
&lt;/p&gt;
&lt;p&gt;
Posted by &lt;a href="mailto:dr@tec_nospam_htalk.at"&gt;Dirk&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Technorati Tags: &lt;a href="http://technorati.com/tag/object+relational" rel=”tag”&gt;object
relational&lt;/a&gt;, &lt;a href="http://technorati.com/tag/getting+started" rel=”tag”&gt;getting
started&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=cffe20b9-5251-4d8b-91fb-8cfc38c2ebdd" /&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,cffe20b9-5251-4d8b-91fb-8cfc38c2ebdd.aspx</comments>
      <category>Genome</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,cffe20b9-5251-4d8b-91fb-8cfc38c2ebdd.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=6e909a93-c064-433a-9873-cfd6187d5884</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,6e909a93-c064-433a-9873-cfd6187d5884.aspx</pingback:target>
      <dc:creator>Christian Hassa</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,6e909a93-c064-433a-9873-cfd6187d5884.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=6e909a93-c064-433a-9873-cfd6187d5884</wfw:commentRss>
      <title>PDC 2007 cancelled/shifted</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,6e909a93-c064-433a-9873-cfd6187d5884.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/ET2KgpRYQsg/PermaLink,guid,6e909a93-c064-433a-9873-cfd6187d5884.aspx</link>
      <pubDate>Sun, 27 May 2007 10:43:07 GMT</pubDate>
      <description>I understand that PDC doesn’t deal with current or soon-to-be-released technology, and frankly, I didn’t epxect to see anything about Orcas there. I find their explanation weird, especially for two points.&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=6e909a93-c064-433a-9873-cfd6187d5884"/&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,6e909a93-c064-433a-9873-cfd6187d5884.aspx</comments>
      <category>General</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,6e909a93-c064-433a-9873-cfd6187d5884.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=00ed89a3-0a23-4fbd-8144-ec499940f292</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,00ed89a3-0a23-4fbd-8144-ec499940f292.aspx</pingback:target>
      <dc:creator>Christian Hassa</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,00ed89a3-0a23-4fbd-8144-ec499940f292.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=00ed89a3-0a23-4fbd-8144-ec499940f292</wfw:commentRss>
      <title>Genome on theserverside.net: article about perceptions of O/RM</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,00ed89a3-0a23-4fbd-8144-ec499940f292.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/I32Fr6I8nyM/PermaLink,guid,00ed89a3-0a23-4fbd-8144-ec499940f292.aspx</link>
      <pubDate>Thu, 15 Mar 2007 14:59:23 GMT</pubDate>
      <description>&lt;p&gt;George Lawton contacted me at the end of February to ask some questions about O/RM as he was working on a story for theserverside.net. &lt;a href="http://www.theserverside.net/news/thread.tss?thread_id=44624"&gt;The story has now been published&lt;/a&gt;, and I think George Lawton and Jack Vaughn did a good job of providing an accurate analysis of the current situation of the O/RM market for .NET.
&lt;/p&gt;


&lt;p&gt; 
When I received George’s email, I was quite surprised that he was inquiring about the situation that people allegedly complain about O/RMs generating quick wins in the beginning that you pay dearly for at a later stage. In his article, you can read how strongly I disagree with this myth and I was pleased to see that other people quoted in his article feel the same.
&lt;/p&gt;
 
&lt;p&gt;
George asked us the following three questions, which I found very interesting to discuss:
&lt;/p&gt;
 
&lt;p&gt;
&lt;ul&gt;
&lt;li&gt;What specific features of Genome make it simpler to use, both initially and over time, than other O/RM tools?&lt;/li&gt;
&lt;li&gt;What have been some of the major challenges in the use of O/RM tools, and what are the ways you have gone about addressing these?&lt;/li&gt;
&lt;li&gt;What specific tips do you have to offer developers in getting the most out of using O/RM tools as part of the software development process?&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
 
&lt;p&gt;
Intrigued by his questions, I put together quite extensive replies – replies that may be of interest to others, too. Based on my answers to George, I have put together this article to outline our thoughts on the issues above and give some advice to developers who are evaluating O/RMs.
&lt;/p&gt;&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=00ed89a3-0a23-4fbd-8144-ec499940f292"/&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,00ed89a3-0a23-4fbd-8144-ec499940f292.aspx</comments>
      <category>Genome</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,00ed89a3-0a23-4fbd-8144-ec499940f292.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=edceaf14-931f-4a65-88a9-267d5d927083</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,edceaf14-931f-4a65-88a9-267d5d927083.aspx</pingback:target>
      <dc:creator>Christian Hassa</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,edceaf14-931f-4a65-88a9-267d5d927083.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=edceaf14-931f-4a65-88a9-267d5d927083</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <title>Using .net locking properly in lazy-initialization implementations</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,edceaf14-931f-4a65-88a9-267d5d927083.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/Qav9VhyS0YQ/PermaLink,guid,edceaf14-931f-4a65-88a9-267d5d927083.aspx</link>
      <pubDate>Mon, 12 Mar 2007 16:57:28 GMT</pubDate>
      <description>&lt;p&gt; 
The Singleton pattern represents a very common way of using lazy initialization with resources. Textbooks usually describe the Singleton as follows:
&lt;/p&gt;

&lt;p&gt;
&lt;pre class="sourceCode"&gt;public class SingletonClass
{
  private static SingletonClass instance;
  public static SingletonClass Instance
  {
    get {
      if (instance == null)
      {
        instance = new SingletonClass(…);
        // do some initialization logic
      }
      return instance;
    }
  }
...
}
&lt;/pre&gt;
&lt;/p&gt;

&lt;p&gt;
However, as any developer quickly realizes - implementing it in this way in a multi-threaded scenario is highly error-prone: if two threads attempt to access Instance at the same time (when it hasn't been created yet), both may run inside the if block and one of the threads will override the instance created by the other. As we tried to defend ourselves against this scenario, we changed the implementation as follows:
&lt;/p&gt;&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=edceaf14-931f-4a65-88a9-267d5d927083"/&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,edceaf14-931f-4a65-88a9-267d5d927083.aspx</comments>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,edceaf14-931f-4a65-88a9-267d5d927083.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=d6e35e09-48c7-42b8-9148-77930613eee3</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,d6e35e09-48c7-42b8-9148-77930613eee3.aspx</pingback:target>
      <dc:creator>Christian Hassa</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,d6e35e09-48c7-42b8-9148-77930613eee3.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=d6e35e09-48c7-42b8-9148-77930613eee3</wfw:commentRss>
      <title>How to get started with Genome</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,d6e35e09-48c7-42b8-9148-77930613eee3.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/beflqnDxVgw/PermaLink,guid,d6e35e09-48c7-42b8-9148-77930613eee3.aspx</link>
      <pubDate>Mon, 12 Mar 2007 11:02:26 GMT</pubDate>
      <description>Let’s be honest about it: getting to know Genome is a non-trivial undertaking. It may seem downright daunting. I want to share with you some of the things I did, hoping that someone might benefit from my experiences.&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=d6e35e09-48c7-42b8-9148-77930613eee3"/&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,d6e35e09-48c7-42b8-9148-77930613eee3.aspx</comments>
      <category>Genome</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,d6e35e09-48c7-42b8-9148-77930613eee3.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=2659b0be-923f-4a7c-9e59-e83cdf1189a7</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,2659b0be-923f-4a7c-9e59-e83cdf1189a7.aspx</pingback:target>
      <dc:creator>Christian Hassa</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,2659b0be-923f-4a7c-9e59-e83cdf1189a7.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=2659b0be-923f-4a7c-9e59-e83cdf1189a7</wfw:commentRss>
      <title>Transient test data for persistent types in Blend Part 2: Binding test data in Blend</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,2659b0be-923f-4a7c-9e59-e83cdf1189a7.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/Dj0-TyuAKqw/PermaLink,guid,2659b0be-923f-4a7c-9e59-e83cdf1189a7.aspx</link>
      <pubDate>Mon, 26 Feb 2007 14:29:32 GMT</pubDate>
      <description>&lt;p&gt;
In &lt;a href="http://blog.genom-e.com/PermaLink,guid,d0c5751d-b561-4f35-877b-d9eb045692c3.aspx"&gt;my previous post&lt;/a&gt; I was discussing about how to mock test data for persistent objects mapped with Genome. Now I want to discuss how to provide this sample data in Blend so the designer building a front end with WPF actually sees how the UI would look like with data.
&lt;/p&gt;&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=2659b0be-923f-4a7c-9e59-e83cdf1189a7"/&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,2659b0be-923f-4a7c-9e59-e83cdf1189a7.aspx</comments>
      <category>Genome</category>
      <category>WPF</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,2659b0be-923f-4a7c-9e59-e83cdf1189a7.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=d0c5751d-b561-4f35-877b-d9eb045692c3</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,d0c5751d-b561-4f35-877b-d9eb045692c3.aspx</pingback:target>
      <dc:creator>Christian Hassa</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,d0c5751d-b561-4f35-877b-d9eb045692c3.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=d0c5751d-b561-4f35-877b-d9eb045692c3</wfw:commentRss>
      <title>Transient test data for persistent types in Blend Part 1: Mocking data provided by Genome</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,d0c5751d-b561-4f35-877b-d9eb045692c3.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/J_7-U3m0iis/PermaLink,guid,d0c5751d-b561-4f35-877b-d9eb045692c3.aspx</link>
      <pubDate>Sat, 24 Feb 2007 14:15:35 GMT</pubDate>
      <description>&lt;p&gt;
We’ve been working on a little research project recently with WPF and created a small (and hopefully handy) application where you can list your contacts synchronized from Microsoft CRM. We store the offline data in a SQL 2005 Compact Edition database and we access the data using Genome.
&lt;/p&gt;
&lt;p&gt;
To make the experiment more exciting we involved a designer in the project, not only to design a cool UI using the features of WPF, but mainly to see how the collaboration between designer and developer works in reality.
&lt;/p&gt;&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=d0c5751d-b561-4f35-877b-d9eb045692c3"/&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,d0c5751d-b561-4f35-877b-d9eb045692c3.aspx</comments>
      <category>Genome</category>
      <category>WPF</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,d0c5751d-b561-4f35-877b-d9eb045692c3.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=520512a0-3685-42cf-aedd-79381fa10909</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,520512a0-3685-42cf-aedd-79381fa10909.aspx</pingback:target>
      <dc:creator>Christian Hassa</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,520512a0-3685-42cf-aedd-79381fa10909.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=520512a0-3685-42cf-aedd-79381fa10909</wfw:commentRss>
      <title>Releasing Genome 3.1</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,520512a0-3685-42cf-aedd-79381fa10909.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/Et4ebOBpfrs/PermaLink,guid,520512a0-3685-42cf-aedd-79381fa10909.aspx</link>
      <pubDate>Tue, 20 Feb 2007 16:03:07 GMT</pubDate>
      <description>&lt;p&gt;
Yesterday we were releasing Genome 3.1. After making quite a big step from Genome 2.6 to 3.0 last November, I thought the 3.1 release would allow us to take a breath, do some polishing on the code and finish some of the stuff that just didn’t make it into 3.0. 
&lt;/p&gt;
&lt;p&gt;
How wrong I was.
&lt;/p&gt;
&lt;p&gt;
The length of the &lt;A href="http://documentation.genom-e.com/Genome/Default.aspx/GenomeDoc/aref_WhatsNew.html"&gt;What’s New for Genome 3.1&lt;/A&gt; will easily tell you that this is not a minor upgrade. Some major improvements have been put into this release, so it is definitely worth upgrading to as soon as possible to 3.1 for everyone working with Genome. 
&lt;/p&gt;&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=520512a0-3685-42cf-aedd-79381fa10909"/&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,520512a0-3685-42cf-aedd-79381fa10909.aspx</comments>
      <category>Genome</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,520512a0-3685-42cf-aedd-79381fa10909.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=0487a411-0908-4985-8297-113979a10402</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,0487a411-0908-4985-8297-113979a10402.aspx</pingback:target>
      <dc:creator>Dirk Rombauts</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,0487a411-0908-4985-8297-113979a10402.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=0487a411-0908-4985-8297-113979a10402</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I started working at TechTalk two weeks ago and one of my first tasks was – naturally
– to get to know Genome. So I browsed through the tutorials and the quickstarts, and
I watched the videos. Those gave me a general understanding of how to work with Genome.
To get a real feel for it, I converted the data access layer of one of my pet projects
to Genome. I know this pet project inside out, and it contains a couple of queries
that are a bit more complex than your basis quickstart query. I felt that this was
a good way to learn the details of Genome: take a project with a classic DAL that
I know very well, and convert it to Genome while keeping all other aspects of the
project. I struggled at first, but after a couple of days I came to grips with Genome
and its query language and after that it went like a breeze.
</p>
        <p>
What I like most about Genome is Query Decomposition. Suppose we have a Document entity
and a Category entity. A Document can be assigned ("tagged") multiple categories,
and there are many documents in each category - a classic m:p relation. In the dark
ages of manual sql code, I'd have to write a stored procedure that gets all documents
from the last 30 days. I'd have to write another stored procedure to get all documents
in a certain category from the past 6 months. Thanks to genome, I have two select
methods on my Document class for these scenarios. The first gets a set of documents
from a specific time interval. The second gets a set of documents from a specific
time interval that belong to a specific category. Using query composition, I can refactor
these methods so that the second method calls the first method and does some more
filtering on the result of the first method. Each idea is expressed only once in code.
Genome takes care of executing just a single sql statement, even though I'm really
calling two methods in my programming code. This is imo the real killer feature of
Genome. 
</p>
        <p>
        </p>
        <p>
Posted by <a href="mailto:dr@tec_nospam_htalk.at">Dirk</a>.
</p>
        <img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=0487a411-0908-4985-8297-113979a10402" />
      </body>
      <title>My First 14 Days With Genome</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,0487a411-0908-4985-8297-113979a10402.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/Szxc5DKb_0o/PermaLink,guid,0487a411-0908-4985-8297-113979a10402.aspx</link>
      <pubDate>Mon, 29 Jan 2007 13:00:59 GMT</pubDate>
      <description>&lt;p&gt;
I started working at TechTalk two weeks ago and one of my first tasks was – naturally
– to get to know Genome. So I browsed through the tutorials and the quickstarts, and
I watched the videos. Those gave me a general understanding of how to work with Genome.
To get a real feel for it, I converted the data access layer of one of my pet projects
to Genome. I know this pet project inside out, and it contains a couple of queries
that are a bit more complex than your basis quickstart query. I felt that this was
a good way to learn the details of Genome: take a project with a classic DAL that
I know very well, and convert it to Genome while keeping all other aspects of the
project. I struggled at first, but after a couple of days I came to grips with Genome
and its query language and after that it went like a breeze.
&lt;/p&gt;
&lt;p&gt;
What I like most about Genome is Query Decomposition. Suppose we have a Document entity
and a Category entity. A Document can be assigned ("tagged") multiple categories,
and there are many documents in each category - a classic m:p relation. In the dark
ages of manual sql code, I'd have to write a stored procedure that gets all documents
from the last 30 days. I'd have to write another stored procedure to get all documents
in a certain category from the past 6 months. Thanks to genome, I have two select
methods on my Document class for these scenarios. The first gets a set of documents
from a specific time interval. The second gets a set of documents from a specific
time interval that belong to a specific category. Using query composition, I can refactor
these methods so that the second method calls the first method and does some more
filtering on the result of the first method. Each idea is expressed only once in code.
Genome takes care of executing just a single sql statement, even though I'm really
calling two methods in my programming code. This is imo the real killer feature of
Genome. 
&lt;p&gt;
&lt;p&gt;
Posted by &lt;a href="mailto:dr@tec_nospam_htalk.at"&gt;Dirk&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=0487a411-0908-4985-8297-113979a10402" /&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,0487a411-0908-4985-8297-113979a10402.aspx</comments>
      <category>Genome</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,0487a411-0908-4985-8297-113979a10402.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://blog.genom-e.com/Trackback.aspx?guid=75ae1727-7072-49df-9b46-a2ac9dd6a493</trackback:ping>
      <pingback:server>http://blog.genom-e.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.genom-e.com/PermaLink,guid,75ae1727-7072-49df-9b46-a2ac9dd6a493.aspx</pingback:target>
      <dc:creator>Christian Hassa</dc:creator>
      <wfw:comment>http://blog.genom-e.com/CommentView,guid,75ae1727-7072-49df-9b46-a2ac9dd6a493.aspx</wfw:comment>
      <wfw:commentRss>http://blog.genom-e.com/SyndicationService.asmx/GetEntryCommentsRss?guid=75ae1727-7072-49df-9b46-a2ac9dd6a493</wfw:commentRss>
      <title>LINQ and object relational mapping</title>
      <guid isPermaLink="false">http://blog.genom-e.com/PermaLink,guid,75ae1727-7072-49df-9b46-a2ac9dd6a493.aspx</guid>
      <link>http://feedproxy.google.com/~r/GenomeTeamblog/~3/7XPF2bE3-w4/PermaLink,guid,75ae1727-7072-49df-9b46-a2ac9dd6a493.aspx</link>
      <pubDate>Fri, 05 Jan 2007 17:55:23 GMT</pubDate>
      <description>&lt;p&gt;
In the recent months there has been a lot of confusion in the community about what LINQ is and what it is not. If you discuss this topic with others and read through the blogs you will find a lot of different perspectives and opinions on LINQ. 
&lt;/p&gt;
&lt;p&gt;
Most of the questions and misconceptions about LINQ I have encountered are about mixing up LINQ with an O/RM system and not understanding the impact of LINQ to .NET based O/RMs. 
&lt;/p&gt;
&lt;p&gt;
This is a brief summary about LINQ and how it relates to O/RMs, using Genome as a concrete example. 
&lt;/p&gt;&lt;img width="0" height="0" src="http://blog.genom-e.com/aggbug.ashx?id=75ae1727-7072-49df-9b46-a2ac9dd6a493"/&gt;</description>
      <comments>http://blog.genom-e.com/CommentView,guid,75ae1727-7072-49df-9b46-a2ac9dd6a493.aspx</comments>
      <category>Genome</category>
      <category>Linq</category>
    <feedburner:origLink>http://blog.genom-e.com/PermaLink,guid,75ae1727-7072-49df-9b46-a2ac9dd6a493.aspx</feedburner:origLink></item>
  </channel>
</rss>
