<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Hartmut Maennel's Blog</title><link>http://blogs.msdn.com/b/hartmutm/</link><description /><dc:language>en</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>A LINQ provider for RDF files - part 2</title><link>http://blogs.msdn.com/b/hartmutm/archive/2006/07/24/677200.aspx</link><pubDate>Tue, 25 Jul 2006 00:49:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:677200</guid><dc:creator>Hartmut Maennel</dc:creator><slash:comments>25</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/hartmutm/rsscomments.aspx?WeblogPostID=677200</wfw:commentRss><comments>http://blogs.msdn.com/b/hartmutm/archive/2006/07/24/677200.aspx#comments</comments><description>&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;For the simple Rdf queries like &lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;IQueryable&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&amp;lt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;&amp;gt; q = &lt;SPAN style="COLOR: blue"&gt;from&lt;/SPAN&gt; x &lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt; rdf&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;from&lt;/SPAN&gt; y &lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt; rdf&lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;where&lt;/SPAN&gt; rdf.A(&lt;?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /&gt;&lt;st1:country-region w:st="on"&gt;&lt;st1:place w:st="on"&gt;germany&lt;/st1:place&gt;&lt;/st1:country-region&gt;, hasAdminDiv, x) &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;amp;&amp;amp; rdf.A(x, isOfType, germanState)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;amp;&amp;amp; rdf.A(x, hasName, y) &lt;BR&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;select&lt;/SPAN&gt; y.Val + &lt;SPAN style="COLOR: maroon"&gt;"&amp;nbsp; &amp;nbsp;["&lt;/SPAN&gt; + x.Val + &lt;SPAN style="COLOR: maroon"&gt;"]"&lt;/SPAN&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;which we are going to support here there is a “normal form” given by&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l1 level1 lfo1; tab-stops: list .5in"&gt;&lt;SPAN style="mso-fareast-font-family: 'Times New Roman'"&gt;&lt;SPAN style="mso-list: Ignore"&gt;-&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;a set of variables, which denote resources or values in an RDF document – in the example above this is {x,y}.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l1 level1 lfo1; tab-stops: list .5in"&gt;&lt;SPAN style="mso-fareast-font-family: 'Times New Roman'"&gt;&lt;SPAN style="mso-list: Ignore"&gt;-&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;a set of constraint triples (subj, pred, obj) where subj, pred, obj are either variables or constants. This is the query condition – in the above example it is&lt;BR&gt;{&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;(&lt;st1:country-region w:st="on"&gt;&lt;st1:place w:st="on"&gt;germany&lt;/st1:place&gt;&lt;/st1:country-region&gt;,hasAdminDiv,x),(x,isOfType,germanState),(x,hasName,y)&lt;/SPAN&gt; }&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l1 level1 lfo1; tab-stops: list .5in"&gt;&lt;SPAN style="mso-fareast-font-family: 'Times New Roman'"&gt;&lt;SPAN style="mso-list: Ignore"&gt;-&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;a “projection function” using these variables which denotes the value which we associate with each “row” – in the above example this is&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;(x,y) =&amp;gt; &lt;SPAN style="mso-no-proof: yes"&gt;y.Val + &lt;SPAN style="COLOR: maroon"&gt;" &lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;["&lt;/SPAN&gt; + x.Val + &lt;SPAN style="COLOR: maroon"&gt;"]"&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;To execute such a query means finding all possible assignments of resources / values to the variables such that all resulting triples are in the axioms of the RDF file, and then applying the projection function to get a set of objects of a certain type (the return type of the projection function – in the above example this is string).&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;The compiler will treat the above query expression as syntactic sugar for an expression like:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;rdf.SelectMany(x =&amp;gt; rdf.Where(y =&amp;gt; Cond(x,y))&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: FR"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;.Select(y =&amp;gt; f(x,y))&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;)&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;where Cond(x,y) is the condition involving rdf.A and f(x,y) is the function that assigns a string to each pair (x,y) of values in the Rdf document.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;The same query could be written in different forms: For example replacing an expression &lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; tab-stops: 395.7pt"&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: FR"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;rdf.Where(y =&amp;gt; Cond1(x,y) &amp;amp;&amp;amp; Cond2(x,y))&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; tab-stops: 395.7pt"&gt;by &lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; tab-stops: 395.7pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;rdf.Where(y =&amp;gt; Cond1(x,y)).Where(z =&amp;gt; Cond2(x,z))&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;should lead to the same normal form.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;So how do we get LINQ to translate these expressions to the above normal form?&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;To get LINQ started, our &lt;SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;Rdf &lt;/SPAN&gt;type has to implement an IQueryable&amp;lt;T&amp;gt; interface, like the System.Data.DLinq.Table&amp;lt;T&amp;gt; does. When we query a database table without conditions, we get the set of all rows in the table. The analog notion for an RDF file (or RDF files, or any set of Rdf triples) is the set of all “Values” in the RDF document, so we implement the interface IQueryable&amp;lt;Value&amp;gt; on Rdf.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;“Value” is the common base type of Literal (meaning a string occurring in an object position in an axiom) and Resource (given by a URI occurring in any position in any axiom).&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Since we usually do not really want to retrieve all values occurring in a document, it does not matter too much what exactly we get when we foreach over a document (e.g. all values or only the resources?), what is more important is the IQueryable part, since that means that now the query operators Where, Select, SelectMany are defined for Rdf.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;The basic observation is that we now can give the normal form of a query corresponding to a Rdf object (variables: {x}, constraints: {}, projection: x =&amp;gt; x), and we can recursively determine the normal form of a query which is constructed out of these with the operators Where, Select and SelectMany.&lt;BR&gt;There is some fine print:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo2; tab-stops: list .5in"&gt;&lt;SPAN style="mso-fareast-font-family: 'Times New Roman'"&gt;&lt;SPAN style="mso-list: Ignore"&gt;1)&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;Variables and variable names:&lt;BR&gt;In &lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;rdf.Where(y =&amp;gt; Cond1(x,y)).Where(z =&amp;gt; Cond2(x,z))&lt;/SPAN&gt; the names y and z correspond to the same variable (which runs over the rdf at the beginning of this expression). We have to be careful to distinguish between variables (that the solver will assign to values) and named references to these variables (like “y” and “z” above).&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo2; tab-stops: list .5in"&gt;&lt;SPAN style="mso-fareast-font-family: 'Times New Roman'"&gt;&lt;SPAN style="mso-list: Ignore"&gt;2)&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;Variables can be defined outside of a (sub)expression:&lt;BR&gt;In &lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;rdf.Where(y =&amp;gt; Cond1(x,y)) &lt;/SPAN&gt;the variable x is defined in an enclosing scope. When we translate a (sub)expression, we always have to give the list of variables in the enclosing scope as a parameter.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo2; tab-stops: list .5in"&gt;&lt;SPAN style="mso-fareast-font-family: 'Times New Roman'"&gt;&lt;SPAN style="mso-list: Ignore"&gt;3)&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;Some restrictions apply:&lt;BR&gt;- We only deal with Where, Select, SelectMany when applied to a Rdf query with identity projection function, i.e. the output is given by a variable and is a sequence of objects of type Value (e.g. not to a sequence of strings).&lt;BR&gt;- The conditions in the Where clause only are of the form Rdf.A(?,?,?), the predicate is always given as a constant, and at least one of the entries is a variable. &lt;BR style="mso-special-character: line-break"&gt;&lt;BR style="mso-special-character: line-break"&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;BR&gt;With these caveats, here is what this recursive algorithm does:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l1 level1 lfo1; tab-stops: list .5in"&gt;&lt;SPAN style="mso-fareast-font-family: 'Times New Roman'"&gt;&lt;SPAN style="mso-list: Ignore"&gt;-&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;Where:&lt;BR&gt;&lt;/B&gt;Source.Where(v =&amp;gt; Cond(v)):&lt;BR&gt;Translate the query expression Source. Assume the output of Source is a variable. Make the name v point to the same variable, translate the condition and add the result&amp;nbsp;to the list of constraints.&lt;BR&gt;The output variable of the new query expression is the same as for Source.&lt;B style="mso-bidi-font-weight: normal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l1 level1 lfo1; tab-stops: list .5in"&gt;&lt;SPAN style="mso-fareast-font-family: 'Times New Roman'"&gt;&lt;SPAN style="mso-list: Ignore"&gt;-&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;SelectMany:&lt;/B&gt;&lt;BR&gt;Source.SelectMany(v =&amp;gt; Seq(v)):&lt;BR&gt;Translate the query expression Source. Assume the output of Source is given by a variable. Make the name v point to the same variable. Add the variables and constraints of Source and Seq together. The projection function of the result is the projection function of Seq.&lt;B style="mso-bidi-font-weight: normal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l1 level1 lfo1; tab-stops: list .5in"&gt;&lt;SPAN style="mso-fareast-font-family: 'Times New Roman'"&gt;&lt;SPAN style="mso-list: Ignore"&gt;-&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;Select:&lt;BR&gt;&lt;/B&gt;Source.Select(v=&amp;gt;f(v)):&lt;BR&gt;Translate the query expression Source. Assume the output of Source is given by a variable. Make the name v point to the same variable. Determine all parameters occurring in f, build a Lambda expression (v1,v2,..,vn) =&amp;gt; f(v1,v2,…,vn) and compile it. This is the projection function of the result. The variables and constraints of the result are the same as from source. &lt;B style="mso-bidi-font-weight: normal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;I attach a VS2005 solution which implements this algorithm. It assumes the May LINQ CTP is installed.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;It contains&amp;nbsp;four projects:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l1 level1 lfo1; tab-stops: list .5in"&gt;&lt;SPAN style="mso-fareast-font-family: 'Times New Roman'"&gt;&lt;SPAN style="mso-list: Ignore"&gt;-&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;LinqToRdf&lt;/B&gt; is the main project which implements this algorithm&lt;BR&gt;It uses an ITriplePovider object which enumerates triples, and an ISolver object that implements a solution algorithm that takes “local information” about the possibilities to complete a triple when the predicate and maybe one of subject and object are given, and computes all the possible solutions of a given query (given as a set of query triples).&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l1 level1 lfo1; tab-stops: list .5in"&gt;&lt;SPAN style="mso-fareast-font-family: 'Times New Roman'"&gt;&lt;SPAN style="mso-list: Ignore"&gt;-&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;RdfXmlReader &lt;/B&gt;is an implementation of ITripleProvider which reads in an RdfXml file. It uses Drive (see last blog entry), you have to modify the reference to Drive.dll in this project to point to your copy of Drive.dll.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l1 level1 lfo1; tab-stops: list .5in"&gt;&lt;SPAN style="mso-fareast-font-family: 'Times New Roman'"&gt;&lt;SPAN style="mso-list: Ignore"&gt;-&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;SimpleSolver &lt;/B&gt;implements a simple algorithm to solve an Rdf query in the above normal form.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l1 level1 lfo1; tab-stops: list .5in"&gt;&lt;SPAN style="mso-fareast-font-family: 'Times New Roman'"&gt;&lt;SPAN style="mso-list: Ignore"&gt;-&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;Demo &lt;/B&gt;uses these assemblies to read in the RDF files&amp;nbsp;containing information about&amp;nbsp;&lt;st1:country-region w:st="on"&gt;Germany&lt;/st1:country-region&gt; and &lt;st1:country-region w:st="on"&gt;France&lt;/st1:country-region&gt; and list all “administrative divisions” of &lt;st1:country-region w:st="on"&gt;Germany&lt;/st1:country-region&gt; and &lt;st1:place w:st="on"&gt;&lt;st1:country-region w:st="on"&gt;France&lt;/st1:country-region&gt;&lt;/st1:place&gt;.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;As always, this sample code is the product of Weekend Evening Rapid Prototyping, it is provided as-is and does not come with any warranty.&lt;BR&gt;You can&amp;nbsp;copy, modify, and use the code for commercial and non-commercial purposes.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;To build the RdfXmlReader project, you need to download Drive.dll from &lt;A href="http://www.driverdf.org/"&gt;http://www.driverdf.org/&lt;/A&gt;, see there for legal restrictions which may apply to this DLL.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=677200" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-00-67-72-00/RdfReader.zip" length="59979" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/b/hartmutm/archive/tags/DLinq/">DLinq</category></item><item><title>A LINQ provider for RDF files</title><link>http://blogs.msdn.com/b/hartmutm/archive/2006/07/10/661512.aspx</link><pubDate>Mon, 10 Jul 2006 19:38:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:661512</guid><dc:creator>Hartmut Maennel</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/hartmutm/rsscomments.aspx?WeblogPostID=661512</wfw:commentRss><comments>http://blogs.msdn.com/b/hartmutm/archive/2006/07/10/661512.aspx#comments</comments><description>&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;The next provider I plan to upload here allows querying an RDF file. From the provider writer’s perspective there is a fundamental difference to the previous “Web page” provider: This provider uses IQueryable instead of IEnumerable and transforms .Net expression trees to query objects that can be executed to perform the query.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;“RDF” stands for “Resource Description Framework”: RDF files express properties of and relations between “resources” like web pages, articles, or in fact any objects that can be characterized by a URI – and since you can define URIs for everything, RDF can describe anything.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;You can find more material about RDF at &lt;A href="http://planetrdf.com/guide/"&gt;http://planetrdf.com/guide/&lt;/A&gt;, you can see examples for RDF files describing&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;&lt;SPAN style="mso-fareast-font-family: 'Times New Roman'"&gt;&lt;SPAN style="mso-list: Ignore"&gt;-&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;parts of the above Web site at &lt;A href="http://planetrdf.com/guide/rss.rdf"&gt;http://planetrdf.com/guide/rss.rdf&lt;/A&gt; (RSS 1.0 is an RDF format)&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;&lt;SPAN style="mso-fareast-font-family: 'Times New Roman'"&gt;&lt;SPAN style="mso-list: Ignore"&gt;-&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;recordings of the Kronos Quartet at &lt;BR&gt;&lt;A href="http://musicbrainz.org/mm-2.1/artist/f5586dfa-7031-4af0-8042-19b6a1170389/6"&gt;http://musicbrainz.org/mm-2.1/artist/f5586dfa-7031-4af0-8042-19b6a1170389/6&lt;/A&gt; &lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;&lt;SPAN style="mso-fareast-font-family: 'Times New Roman'"&gt;&lt;SPAN style="mso-list: Ignore"&gt;-&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;geographical / political / statistical data about &lt;?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /&gt;&lt;st1:place w:st="on"&gt;&lt;st1:country-region w:st="on"&gt;Germany&lt;/st1:country-region&gt;&lt;/st1:place&gt; at &lt;BR&gt;&lt;A href="http://www.daml.org/2003/09/factbook/gm"&gt;http://www.daml.org/2003/09/factbook/gm&lt;/A&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;The basic data structure used by an RDF file is a list of “(subject, predicate, object)” triples, where the subject and predicate have to be “resources”, while the object can be either a resource or a literal value (which we will just interpret&amp;nbsp;as a string).&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;BR&gt;This RDF structure can be stored in different ways; the most common is an XML format. There is an open source RDF parser called “Drive” (written in C#) which reads in such a RDFXML file and exposes the content as triples; you can download it at &lt;A href="http://www.driverdf.org/"&gt;http://www.driverdf.org/&lt;/A&gt;.&lt;BR style="mso-special-character: line-break"&gt;&lt;BR style="mso-special-character: line-break"&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;To see how the above RDF file stores the names of the states of &lt;st1:country-region w:st="on"&gt;&lt;st1:place w:st="on"&gt;Germany&lt;/st1:place&gt;&lt;/st1:country-region&gt;, the LINQ provider will allow you to use the following query:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;...&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;FONT color=#008080 size=2&gt;RdfXmlDoc &lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;rdfGermany = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;&lt;FONT color=#008080 size=2&gt;RdfXmlDoc&lt;/FONT&gt;&lt;/SPAN&gt;(fileG&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;ermany);&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;FONT color=#008080 size=2&gt;ISolver&lt;/FONT&gt;&lt;FONT size=2&gt; solver = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; SimpleSolver.&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Solver&lt;/FONT&gt;&lt;FONT size=2&gt;();&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Rdf&lt;/FONT&gt;&lt;FONT size=2&gt; rdf = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Rdf&lt;/FONT&gt;&lt;FONT size=2&gt;(solver);&lt;BR&gt;rdf.LoadRdf(rdfGermany);&lt;/P&gt;&lt;/FONT&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;string&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; nsRdf = &lt;SPAN style="COLOR: maroon"&gt;"http://www.w3.org/1999/02/22-rdf-syntax-ns#"&lt;/SPAN&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;...&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;string&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; isOfType = nsRdf + &lt;SPAN style="COLOR: maroon"&gt;"type"&lt;/SPAN&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;string&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; &lt;st1:country-region w:st="on"&gt;&lt;st1:place w:st="on"&gt;germany&lt;/st1:place&gt;&lt;/st1:country-region&gt; = nsCountries + &lt;SPAN style="COLOR: maroon"&gt;"GM"&lt;/SPAN&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;string&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; hasAdminDiv = nsFactbookOnt + &lt;SPAN style="COLOR: maroon"&gt;"administrativeDivision"&lt;/SPAN&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;string&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; hasName = nsFactbookOnt + &lt;SPAN style="COLOR: maroon"&gt;"name"&lt;/SPAN&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;string&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; germanState = rdfGermany.BaseNamespace + &lt;SPAN style="COLOR: maroon"&gt;"#State"&lt;/SPAN&gt;;&lt;/SPAN&gt; &lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;IQueryable&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&amp;lt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;&amp;gt; q = &lt;SPAN style="COLOR: blue"&gt;from&lt;/SPAN&gt; x &lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt; rdf&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;from&lt;/SPAN&gt; y &lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt; rdf&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;where&lt;/SPAN&gt; rdf.A(&lt;st1:country-region w:st="on"&gt;&lt;st1:place w:st="on"&gt;germany&lt;/st1:place&gt;&lt;/st1:country-region&gt;, hasAdminDiv, x) &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&amp;amp;&amp;amp; rdf.A(x, isOfType, germanState)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&amp;amp;&amp;amp; rdf.A(x, hasName, y) &lt;BR&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;select&lt;/SPAN&gt; y.Val + &lt;SPAN style="COLOR: maroon"&gt;"&amp;nbsp; &amp;nbsp;["&lt;/SPAN&gt; + x.Val + &lt;SPAN style="COLOR: maroon"&gt;"]"&lt;/SPAN&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;RDF and additional layers on top of RDF (RDFS, OWL, OWL Rules) specify how additional triples can be inferred from the assertions in the RDF (OWL, …) files, but in this example this is not used, the &lt;SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;FONT color=#000000&gt;rdf&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;.A(…)&lt;/SPAN&gt;expressions only consider the assertions in the RDF file themselves.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;In the next blog entry I will describe the translation from LINQ queries to “RdfExpression”s which can be executed to efficiently search the Rdf structure for the required matches.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;(To be continued…)&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=661512" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/hartmutm/archive/tags/DLinq/">DLinq</category></item><item><title>A LINQ provider for Web queries</title><link>http://blogs.msdn.com/b/hartmutm/archive/2006/06/12/628382.aspx</link><pubDate>Mon, 12 Jun 2006 19:14:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:628382</guid><dc:creator>Hartmut Maennel</dc:creator><slash:comments>17</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/hartmutm/rsscomments.aspx?WeblogPostID=628382</wfw:commentRss><comments>http://blogs.msdn.com/b/hartmutm/archive/2006/06/12/628382.aspx#comments</comments><description>&lt;P&gt;To start a series of "LINQ provider" posts, today I upload a provider sample that in some sense treats the Internet as a database: For a&amp;nbsp;SQL Server database, you can&amp;nbsp;make tables in a database accessible to LINQ by writing&amp;nbsp;classes with attributes that define how objects of these classes are retrieved from rows in tables.&amp;nbsp;LINQ can then use these classes&amp;nbsp;to issue queries against the database.&amp;nbsp;Similarly, this provider&amp;nbsp;allows adding attributes to classes to&amp;nbsp;specify how such objects are retrieved from&amp;nbsp;Web pages, and you can then issue LINQ queries against them.&lt;/P&gt;
&lt;P&gt;The project "WebLinq" in the attached solution contains this provider - it is not very sophisticated, it just contains three files:&lt;BR&gt;- WebLinqAttributes.cs contains the attributes that are recognized&lt;BR&gt;- WebContext.cs is the class your WebLinq enabled classes&amp;nbsp;inherit from&lt;BR&gt;- Utils.cs contains helper functions to GET / POST to a web site and to find substrings in a text.&lt;/P&gt;
&lt;P&gt;The project "WebSources" defines some classes for&amp;nbsp;&lt;BR&gt;- Searching for articles in the&amp;nbsp;CiteSeer web&amp;nbsp;sites&amp;nbsp;(see below)&lt;BR&gt;- Searching for articles in the MSDN web sites&lt;BR&gt;- Translating words / sentences&lt;BR&gt;- Integrating functions of one variable&lt;BR&gt;- Looking up the current values of stocks from the company symbol&lt;/P&gt;
&lt;P&gt;The project "SimpleDemos" uses these two DLLs to demonstrate the last three classes.&lt;BR&gt;&lt;BR&gt;The project "TestWebLinq" demonstrates the access to the CiteSeer web sites.&lt;/P&gt;
&lt;P&gt;CiteSeer is a database of computer science articles; you can search for articles by keywords, and obtain information about articles, and often even retrieve them directly from the Web site.&lt;BR&gt;To use the CiteSeer demo, enter for example "Support Vector Machines" in the text box labeled "Search terms", and click on the "Retrieve" button. It will take some while to visit the web pages which list available articles, to visit the web page for each article, retrieve the information from this article, and access a another web page for details, but then you should see a list of paragraphs which contain&lt;BR&gt;- Author's name(s)&lt;BR&gt;- Title and year&lt;BR&gt;- Some three lines of introduction&lt;BR&gt;- URL for this article&lt;BR&gt;- URL for downloading the article as pdf file&lt;BR&gt;- Information about the rights for this article&lt;/P&gt;
&lt;P&gt;If you are only interested in new articles, try entering 2002 in the "Publication year &amp;gt;=" text field and click again on "Retrieve" (currently I get 3 results back).&lt;BR&gt;&lt;BR&gt;Here is how the corresponding query looks in the code:&lt;BR&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&lt;BR&gt;var &lt;FONT color=#000000&gt;doc&lt;/FONT&gt; = &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;GoogleCiteSeer&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT color=#000000&gt;(searchTerms,0);&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;var&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; query = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;from&lt;/FONT&gt;&lt;FONT size=2&gt; art &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;in&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; doc.Articles&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;where&lt;/FONT&gt;&lt;FONT size=2&gt; art.details.Document != &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;null&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&amp;amp;&amp;amp; art.details.Document.bibtex != &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;null&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&amp;amp;&amp;amp; art.details.Document.bibtex.year&amp;gt;=minYear&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;select&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; art.details;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;Here is an example for a class that defines how to read the "BibTeX" part of the Web page with details for an article:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;class&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;CsBibTex&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; {&lt;BR&gt;&amp;nbsp; [&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;StartPart&lt;/FONT&gt;&lt;FONT size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"author = \""&lt;/FONT&gt;&lt;FONT size=2&gt;)] [&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;EndPart&lt;/FONT&gt;&lt;FONT size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"\""&lt;/FONT&gt;&lt;FONT size=2&gt;)] &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; author;&lt;BR&gt;&amp;nbsp; [&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;StartPart&lt;/FONT&gt;&lt;FONT size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"title = \""&lt;/FONT&gt;&lt;FONT size=2&gt;)]&amp;nbsp; [&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;EndPart&lt;/FONT&gt;&lt;FONT size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"\""&lt;/FONT&gt;&lt;FONT size=2&gt;)] &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; title;&lt;BR&gt;&amp;nbsp; [&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;StartPart&lt;/FONT&gt;&lt;FONT size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"year = "&lt;/FONT&gt;&lt;FONT size=2&gt;)]&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;EndPart&lt;/FONT&gt;&lt;FONT size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;","&lt;/FONT&gt;&lt;FONT size=2&gt;)]&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; year;&lt;BR&gt;}&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;This sample code is provided as-is and does not come with any warranty. &lt;BR&gt;You can&amp;nbsp;modify and use the code for commercial and non-commercial purposes.&lt;/FONT&gt;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=628382" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-00-62-83-82/WebLinq.zip" length="42279" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/b/hartmutm/archive/tags/DLinq/">DLinq</category></item><item><title>Workaround: Smart Tags in C# IDE do not work correctly in LINQ preview</title><link>http://blogs.msdn.com/b/hartmutm/archive/2006/05/23/604978.aspx</link><pubDate>Tue, 23 May 2006 12:40:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:604978</guid><dc:creator>Hartmut Maennel</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/hartmutm/rsscomments.aspx?WeblogPostID=604978</wfw:commentRss><comments>http://blogs.msdn.com/b/hartmutm/archive/2006/05/23/604978.aspx#comments</comments><description>&lt;P&gt;In&amp;nbsp;the&amp;nbsp;LINQ preview (CTP May 2006), the Smart Tags functionality in the C# IDE&amp;nbsp;does not work correctly. In particular, I miss the "Resolve" feature that puts in the necessary "using" statements automatically.&amp;nbsp;But the&amp;nbsp;good news is that it is easy to get this functionality back:&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: Calibri"&gt;&lt;FONT color=#0000ff size=2&gt;1. Start up RegEdit.exe&lt;BR&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: Calibri"&gt;&lt;FONT color=#0000ff size=2&gt;2. Open HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\Packages\{A066E284-DCAB-11D2-B551-00C04F68D4DB}\SatelliteDLL&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: Calibri"&gt;&lt;FONT color=#0000ff size=2&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: Calibri"&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: Calibri"&gt;&lt;FONT color=#0000ff size=2&gt;3. Edit the "Path" value and change it from "C:\Program Files\Microsoft Visual Studio 8\VC#\VCSPackages\1033\" to "C:\Program Files\Microsoft Visual Studio 8\VC#\VCSPackages\"&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: Calibri"&gt;&lt;FONT color=#0000ff size=2&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: Calibri"&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: Calibri"&gt;&lt;FONT color=#0000ff size=2&gt;4. Then open a console window, go to the directory where your Visual Studio devenv.exe is located (e.g. C:\Program Files\Microsoft Visual Studio 8\Common7\IDE) and run&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/SPAN&gt;&lt;FONT size=2&gt;&lt;SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: Calibri"&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;devenv /setup /resetuserdata /resetsettings &lt;BR&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: Calibri"&gt;&lt;FONT color=#0000ff&gt;(be patient, this takes a while).&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT color=#0000ff size=2&gt;&lt;SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: Calibri"&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT color=#000000&gt;&lt;SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: Calibri"&gt;&lt;FONT color=#000000 size=2&gt;See &lt;/FONT&gt;&lt;A title=http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=419975&amp;amp;SiteID=1 href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=419975&amp;amp;SiteID=1"&gt;&lt;FONT size=2&gt;http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=419975&amp;amp;SiteID=1&lt;/FONT&gt;&lt;/A&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=604978" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/hartmutm/archive/tags/DLinq/">DLinq</category></item><item><title>Linq CTP May 2006 is released</title><link>http://blogs.msdn.com/b/hartmutm/archive/2006/05/10/594850.aspx</link><pubDate>Wed, 10 May 2006 15:46:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:594850</guid><dc:creator>Hartmut Maennel</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/hartmutm/rsscomments.aspx?WeblogPostID=594850</wfw:commentRss><comments>http://blogs.msdn.com/b/hartmutm/archive/2006/05/10/594850.aspx#comments</comments><description>&lt;P class=MsoNormal&gt;&lt;FONT face=Arial color=navy size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: navy; FONT-FAMILY: Arial"&gt;Read about it here: &lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Arial color=navy size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: navy; FONT-FAMILY: Arial"&gt;&lt;A title=http://msdn.microsoft.com/netframework/future/ href="http://msdn.microsoft.com/netframework/future/"&gt;http://msdn.microsoft.com/netframework/future/&lt;/A&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face=Arial color=navy size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: navy; FONT-FAMILY: Arial"&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face=Arial color=navy size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: navy; FONT-FAMILY: Arial"&gt;Or go directly&amp;nbsp;to the download page:&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face=Arial color=navy size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: navy; FONT-FAMILY: Arial"&gt;&lt;A title=http://www.microsoft.com/downloads/details.aspx?familyid=1e902c21-340c-4d13-9f04-70eb5e3dceea&amp;amp;displaylang=en href="http://www.microsoft.com/downloads/details.aspx?familyid=1e902c21-340c-4d13-9f04-70eb5e3dceea&amp;amp;displaylang=en"&gt;http://www.microsoft.com/downloads/details.aspx?familyid=1e902c21-340c-4d13-9f04-70eb5e3dceea&amp;amp;displaylang=en&lt;/A&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=594850" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/hartmutm/archive/tags/DLinq/">DLinq</category></item><item><title>Difference between SQL and .Net Framework built in functions</title><link>http://blogs.msdn.com/b/hartmutm/archive/2006/02/10/529853.aspx</link><pubDate>Sat, 11 Feb 2006 00:43:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:529853</guid><dc:creator>Hartmut Maennel</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/hartmutm/rsscomments.aspx?WeblogPostID=529853</wfw:commentRss><comments>http://blogs.msdn.com/b/hartmutm/archive/2006/02/10/529853.aspx#comments</comments><description>&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;A common problem when using different programming languages like SQL on the server and C# or VB on the client is that certain functions are almost the same, but not completely. A good example is SQL Round vs. CLR Math.Round.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;For example, rounding to the next integer would round 2.1 and 2.499 to 2, 2.501 and 2.987 to 3, but different implementations do different things with 2.5:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;On SQL Server, Round always rounds up a trailing 5 (where “up” means that for positive numbers, the result is greater. For negative numbers, only the absolute value goes up: The result is actually lower).&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;In the CLR Math class, Math.Round uses “Banker’s rounding”, which means that a trailing 5 is rounded either up or down such that the result is even.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;DLinq sits between the managed languages and SQL, it allows users to write an expression e.g. in C#, which is then executed as a SQL expression.&lt;BR&gt;Now DLinq has a problem: Should the semantics be the one of SQL or the one of C#? This has been debated in our team some while ago, and probably we will debate it again before we release the next CTP.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Here are some options:&lt;BR style="mso-special-character: line-break"&gt;&lt;BR style="mso-special-character: line-break"&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;1) Our current solution translates to the SQL built in function if its meaning is “reasonable close” to the .Net Framework function. So Math.Round translates to SQL’s Round function. &lt;BR style="mso-special-character: line-break"&gt;&lt;BR style="mso-special-character: line-break"&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;2) We could translate Math.Round(x) to some SQL expression in x that behaves in the same way as Math.Round(x) on the client.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;3) We could have 1 as the default behavior, but add libraries of additional functions that behave the same on SQL and .Net, one that does the Banker’s rounding in both cases, one that does the SQL “always rounding up” in both cases.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;One reason we went with 1 instead of 2 is that the performance is much better than for a special expression that would replace the simple ROUND function.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Since it could both be said that developers expect that Math.Round translates to SQL’s ROUND or that it behaves the same as CLR’s Math.Round on the client, we went for the simple and efficient solution.&lt;BR&gt;One argument against 3 is that it only solves the problem for users who know the problem and know where to look for these functions.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;What are your thoughts? Would you care at all? Do you strongly prefer another solution? Would you need additional libraries?&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=529853" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/hartmutm/archive/tags/DLinq/">DLinq</category></item><item><title>DLinq Providers</title><link>http://blogs.msdn.com/b/hartmutm/archive/2006/02/09/529036.aspx</link><pubDate>Thu, 09 Feb 2006 22:08:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:529036</guid><dc:creator>Hartmut Maennel</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/hartmutm/rsscomments.aspx?WeblogPostID=529036</wfw:commentRss><comments>http://blogs.msdn.com/b/hartmutm/archive/2006/02/09/529036.aspx#comments</comments><description>&lt;P&gt;The last weeks I have been working on DLinq "providers". The idea is to connect with DLinq to other databases than SQL Server, so we may need to use other mechanisms to connect to the database, need to generate slightly different SQL etc. As a first experiment&amp;nbsp;I wrote a basic Jet provider (to access Access databases). It has not been decided whether and how this experiment will be made public, but I would be interested to know what customers would want.&lt;BR&gt;Obviously&amp;nbsp;it would be interesting to look at other databases, and as a private hobbyist I probably would just download one of the freely available databases and try it, but being&amp;nbsp;an employee of a software company, clicking "I Agree" on the "End User License Agreement" of another software company is a non-trivial operation... So besides Access I was looking at other more exotic possibilities, and one thing that occasionally comes up in customer interactions is Analysis Server. Of course, this has a different flavor than Access since it has more fundamental differences to SQL Server, but it is an interesting idea.&lt;BR&gt;I should make explicit that there are&amp;nbsp;currently no plans&amp;nbsp;for adding such a provider in any form, since right now other things (like accessing other databases) are much more important. But I am still curious how customers would see this, is that something you would use? How big would the benefit be for you?&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=529036" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/hartmutm/archive/tags/DLinq/">DLinq</category></item><item><title>Bio</title><link>http://blogs.msdn.com/b/hartmutm/archive/2005/10/31/487480.aspx</link><pubDate>Tue, 01 Nov 2005 01:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:487480</guid><dc:creator>Hartmut Maennel</dc:creator><slash:comments>0</slash:comments><description>&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;I joined Microsoft &lt;?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /&gt;&lt;st1:country-region w:st="on"&gt;Germany&lt;/st1:country-region&gt; in 1998, and moved to the Visual Studio Group in &lt;st1:City w:st="on"&gt;&lt;st1:place w:st="on"&gt;Redmond&lt;/st1:place&gt;&lt;/st1:City&gt; in 2000. The last two years I have been working in the C# product unit, currently in the DLinq team, and plan to blog about DLinq from time to time. The current web site for LINQ and DLinq is here: &lt;A href="http://msdn.microsoft.com/netframework/future/linq/"&gt;http://msdn.microsoft.com/netframework/future/linq/&lt;/A&gt; &lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Before joining Microsoft I studied mathematics in &lt;st1:City w:st="on"&gt;Bonn&lt;/st1:City&gt;, &lt;st1:country-region w:st="on"&gt;Germany&lt;/st1:country-region&gt; and &lt;st1:place w:st="on"&gt;&lt;st1:City w:st="on"&gt;Cambridge&lt;/st1:City&gt;, &lt;st1:country-region w:st="on"&gt;UK&lt;/st1:country-region&gt;&lt;/st1:place&gt; and worked as a mathematician at &lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=DE style="mso-ansi-language: DE"&gt;Max-Planck-Institut für Mathematik, Bonn, Germany,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Institute for Advanced Study, &lt;st1:place w:st="on"&gt;&lt;st1:City w:st="on"&gt;Princeton&lt;/st1:City&gt;, &lt;st1:State w:st="on"&gt;NJ&lt;/st1:State&gt;&lt;/st1:place&gt;,&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Katholische &lt;st1:place w:st="on"&gt;&lt;st1:City w:st="on"&gt;Universität Eichstätt&lt;/st1:City&gt;, &lt;st1:country-region w:st="on"&gt;Germany&lt;/st1:country-region&gt;&lt;/st1:place&gt;.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;As a hobby, I am still interested in some mathematical aspects of Computer Science, and may also blog about that.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=487480" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/hartmutm/archive/tags/General/">General</category></item></channel></rss>