<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6184851556979812172</id><updated>2011-07-31T14:29:42.853+10:00</updated><category term='c#'/><category term='random thoughts'/><category term='xceed'/><category term='ui'/><category term='linq'/><category term='f#'/><category term='motorbikes'/><category term='wpf'/><category term='maths'/><category term='software development'/><title type='text'>Math Geek Coder</title><subtitle type='html'>Software Development, Math and Random Thoughts</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>31</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-7081938869334708807</id><published>2009-07-22T19:50:00.001+10:00</published><updated>2009-07-22T20:57:27.228+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='random thoughts'/><title type='text'>Bing! - My Claim to Fame</title><content type='html'>&lt;p&gt;Judging by the date of my last post, it turns out that the “it’s the thought that counts” - is all lies!&amp;#160;&amp;#160; Despite my best intentions, an entire year has disappeared into the ether.&lt;/p&gt;  &lt;p&gt;While away from my blogosphere I have continued my programming and my math/statistics degree, but I have changed jobs (10 months ago) – which brings me to this post.&lt;/p&gt;  &lt;p&gt;My ‘new’ employer is “Bing Technologies” and a fun trivia fact is that Microsoft bought the &lt;a href="http://www.bing.com"&gt;www.bing.com&lt;/a&gt; domain from us.&lt;/p&gt;  &lt;p&gt;Cool huh!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-7081938869334708807?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/7081938869334708807/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=7081938869334708807' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/7081938869334708807'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/7081938869334708807'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2009/07/bing-my-claim-to-fame.html' title='Bing! - My Claim to Fame'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-3844523271987808713</id><published>2008-08-01T17:45:00.000+10:00</published><updated>2008-07-31T17:52:41.162+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='f#'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Structure Inlining with .Net 3.5 SP1</title><content type='html'>I just &lt;a href="http://blogs.msdn.com/clrcodegeneration/archive/2007/11/02/how-are-value-types-implemented-in-the-32-bit-clr-what-has-been-done-to-improve-their-performance.aspx"&gt;stumbled on&lt;/a&gt; a fascinating performance improvement coming up in .Net 3.5 SP1.&lt;br /&gt;&lt;br /&gt;When working with value types (structs) the JIT currently hits the stack each time you access a field - which is quite inefficient.&lt;br /&gt;&lt;br /&gt;In SP1 they've added an algorithm called &amp;quot;value type scalar replacement&amp;quot;; which intuitively does exactly what it sounds like!&lt;br /&gt;&lt;br /&gt;Take the following code:&lt;br /&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; MyMethod1(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; v)&lt;br /&gt;{&lt;br /&gt;    Point point;  &lt;span style="color: #008000"&gt;// gets a stack location.&lt;/span&gt;&lt;br /&gt; &lt;br /&gt;    &lt;span style="color: #008000"&gt;// All 3 field accesses involve stack operations.&lt;/span&gt;&lt;br /&gt;    point.x = v; &lt;br /&gt;    point.y = v * 2;&lt;br /&gt; &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; point.x;&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;The JIT will replace the value type (Point is a struct) with scalars:&lt;br /&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; MyMethod2(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; v)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; x; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; y;  &lt;span style="color: #008000"&gt;// Was &amp;#8220;struct point;&amp;#8221;. Now replaced by x and y.&lt;/span&gt;&lt;br /&gt;    x = v; &lt;br /&gt;    y = v * 2;&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; x;&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;After the JIT inlines the structure, it can optimise the routine by placing the integers on the register rather than the stack.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What's the difference?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;We are roughly looking at a 10x improvement! (Using a quick and dodgy test app) &lt;br /&gt;&lt;br /&gt;This is fantastic, especially when dealing with lots of structs like points and rectangles etc.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What's the catch?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;This isn't magically going to work on all your value types; there are strict guidelines when this replacement can occur:&lt;br /&gt;&lt;br /&gt;- The value type must have no more than 4 fields&lt;br /&gt;&lt;br /&gt;- These fields must be value types, or object references&lt;br /&gt;&lt;br /&gt;- You must use [StructLayout(LayoutKind.Sequential)], which is the default anyhow.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There some other catches, but if you are creating complicated structures, you really should think about making them a class.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;More Improvements&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;This is just a snippet of the algorithm, whereas the &lt;a href="http://blogs.msdn.com/clrcodegeneration/archive/2007/11/02/how-are-value-types-implemented-in-the-32-bit-clr-what-has-been-done-to-improve-their-performance.aspx"&gt;original article&lt;/a&gt; explains it in much more detail.&lt;br /&gt;&lt;br /&gt;BTW: This is in the CLR, so all .Net languages benefit!  And of course this includes &lt;a href="http://www.quanttec.com/fparsec/#performance"&gt;F# and FParsec.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Cheers to SP1!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-3844523271987808713?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/3844523271987808713/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=3844523271987808713' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/3844523271987808713'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/3844523271987808713'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2008/07/structure-inlining-with-net-35-sp1.html' title='Structure Inlining with .Net 3.5 SP1'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-6244597881515494393</id><published>2008-07-23T17:29:00.006+10:00</published><updated>2008-07-23T17:57:54.128+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='linq'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Advanced Domain Model queries using Linq - Part IV</title><content type='html'>This &lt;em&gt;should&lt;/em&gt; be the last part in my &lt;a href="http://mathgeekcoder.blogspot.com/2008/07/advanced-domain-model-queries-using.html"&gt;series&lt;/a&gt; &lt;a href="http://mathgeekcoder.blogspot.com/2008/07/advanced-domain-model-queries-using_16.html"&gt;of&lt;/a&gt; &lt;a href="http://mathgeekcoder.blogspot.com/2008/07/advanced-domain-model-queries-using_17.html"&gt;posts&lt;/a&gt;.&amp;#160; In this part I'll cover support for parameters via method calls.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Parameter Support (Contrived Example)&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Continuing the Library example, how would you query the books that will be overdue next week?&lt;br /&gt;&lt;br /&gt;Well you could write the following:  &lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; nextWeek = &lt;span style="color: #0000ff"&gt;from&lt;/span&gt; a &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; repository.AsQueryable()&lt;br /&gt;               &lt;span style="color: #0000ff"&gt;where&lt;/span&gt; a.CheckOverdue(DateTime.Today.AddDays(7))&lt;br /&gt;               &lt;span style="color: #0000ff"&gt;select&lt;/span&gt; a;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;strong&gt;How it works&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The CheckOverdue Property simply returns a Lambda Expression as it's result.&lt;br /&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt; CheckOverdueProperty : QueryProperty&amp;lt;Loan, Func&amp;lt;DateTime, &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt;&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; CheckOverdueProperty()&lt;br /&gt;        : &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;(x =&amp;gt; y =&amp;gt; (x.DateReturned == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; (y - x.DateBorrowed).TotalDays &amp;gt; x.LoanPeriod))&lt;br /&gt;    { }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;I've modified the expression parsing routines to support parameters (including multiple) and even nested lambdas! &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Nested Lambdas?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;I can't really see the need for it, but hey... why not!  Curry anyone? :)&lt;br /&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyProperty : QueryProperty&amp;lt;Loan, Func&amp;lt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;, Func&amp;lt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;, Func&amp;lt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;double&lt;/span&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; MyProperty()&lt;br /&gt;        : &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;(a =&amp;gt; x =&amp;gt; y =&amp;gt; z =&amp;gt; x + y + z + a.LoanPeriod)&lt;br /&gt;    { }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;So how would you call such a monstrosity?&lt;br /&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; test = &lt;span style="color: #0000ff"&gt;from&lt;/span&gt; a &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; repository.AsQueryable()&lt;br /&gt;           &lt;span style="color: #0000ff"&gt;select&lt;/span&gt; a.MyProperty(5)(4)(3);&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;But check out the SQL!  Great work Linq to Sql guys!&lt;br /&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;CONVERT&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;Float&lt;/span&gt;,5 + 4 + 3)) + [t0].[LoanPeriod] &lt;span style="color: #0000ff"&gt;AS&lt;/span&gt; [&lt;span style="color: #0000ff"&gt;value&lt;/span&gt;]&lt;br /&gt;&lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; [dbo].[Loan] &lt;span style="color: #0000ff"&gt;AS&lt;/span&gt; [t0]&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;strong&gt;Declaration Syntax&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;If you're particularly astute, you'll have noticed that my syntax for declaring a QueryProperty has changed slightly since the last post. &lt;br /&gt;&lt;br /&gt;Here's the class declaration of the CheckOverdue Property:&lt;br /&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;[QueryProperty(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(CheckOverdueProperty))]&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; CheckOverdue(DateTime date)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; CheckOverdueProperty.GetValue&amp;lt;CheckOverdueProperty&amp;gt;(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;)(date);&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Although this is a method, you can still define it as a property (notice that I return a lambda expression).&lt;br /&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;[QueryProperty(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(CheckOverdueProperty))]&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Func&amp;lt;DateTime, &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&amp;gt; CheckOverdue&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; CheckOverdueProperty.GetValue&amp;lt;CheckOverdueProperty&amp;gt;(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;); }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;strong&gt;So What's Changed?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Well, QueryProperties no longer derive from an Attribute class.&amp;#160; Although it worked, I felt dirty about it.&lt;br /&gt;&lt;br /&gt;I borrowed from &lt;a href="http://www.iridescence.no/Posts/Linq-the-Specification-Pattern-and-Encapsulation.aspx"&gt;Fredrik's syntax&lt;/a&gt; and pass the property type to the Attribute - much cleaner. &lt;br /&gt;&lt;br /&gt;Since I'm no longer defining the QueryProperty as static, I had to change the way it is referenced by the class property. &lt;br /&gt;&lt;br /&gt;The code above shows my attempt at making this easy, yet efficient - but it's up to you how to implement it.&amp;#160; E.g. this would work well too:&lt;br /&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;[QueryProperty(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(CheckOverdueProperty))]&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Func&amp;lt;DateTime, &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&amp;gt; CheckOverdue&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; CheckOverdueProperty.Value(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;); }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; CheckOverdueProperty CheckOverdueProperty = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CheckOverdueProperty();&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;If you can think of better ways I'd love to hear it!&amp;#160;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Expression Parser&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Since I posted the parser code in my last post, here it is again - and my has it grown!&lt;br /&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 350px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt; QueryPropertyEvaluator : ExpressionVisitor&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000"&gt;// Basic member access support for QueryProperties&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; Expression VisitMemberAccess(MemberExpression m)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (m.Expression != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; property = GetProperty(m.Member);&lt;br /&gt; &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (property != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Expression.Invoke(property.GetExpression(), m.Expression);&lt;br /&gt;        }&lt;br /&gt; &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.VisitMemberAccess(m);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    &lt;span style="color: #008000"&gt;// Support method call abstractions over QueryProperties&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;// Assumes method call has same parameters (in order!) as QueryProperty&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;// Also supports static methods, as long as first parameter is the class object&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; Expression VisitMethodCall(MethodCallExpression m)&lt;br /&gt;    {&lt;br /&gt;        Expression obj = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Visit(m.Object);&lt;br /&gt;        IEnumerable&amp;lt;Expression&amp;gt; args = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.VisitExpressionList(m.Arguments);&lt;br /&gt; &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; property = GetProperty(m.Method);&lt;br /&gt; &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (property != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (obj != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color: #008000"&gt;// Method on QueryProperty class&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; VisitLambdaInvocation(Expression.Invoke(property.GetExpression(), obj), args);&lt;br /&gt;            }&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color: #008000"&gt;// Assumes static method where first parameter is object instance&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; VisitLambdaInvocation(Expression.Invoke(property.GetExpression(), args.First()), args.Skip(1));&lt;br /&gt;            }&lt;br /&gt;        } &lt;br /&gt; &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (obj != m.Object || args != m.Arguments)&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Expression.Call(obj, m.Method, args);&lt;br /&gt; &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; m;&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    &lt;span style="color: #008000"&gt;// Support lambda expressions within QueryProperties&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; Expression VisitInvocation(InvocationExpression iv)&lt;br /&gt;    {&lt;br /&gt;        IEnumerable&amp;lt;Expression&amp;gt; args = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.VisitExpressionList(iv.Arguments);&lt;br /&gt;        Expression expr = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Visit(iv.Expression);&lt;br /&gt; &lt;br /&gt;        &lt;span style="color: #008000"&gt;// Rewrite InvokeExpression - Folds out inner lambda&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (expr.NodeType == ExpressionType.Invoke)&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; VisitLambdaInvocation((InvocationExpression)expr, args);&lt;br /&gt; &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (args != iv.Arguments || expr != iv.Expression)&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Expression.Invoke(expr, args);&lt;br /&gt; &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; iv;&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;    &lt;span style="color: #008000"&gt;// Recursively 'flattens' the lambda invocation expressions&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;// Rewrites the nested lambda expression tree to work with Linq to SQL&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; Expression VisitLambdaInvocation(Expression expression, IEnumerable&amp;lt;Expression&amp;gt; args)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (expression.NodeType != ExpressionType.Invoke)&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Expression.Invoke(expression, args);&lt;br /&gt; &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; invoke = (InvocationExpression)expression;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; lambda = (LambdaExpression)invoke.Expression;&lt;br /&gt; &lt;br /&gt;        &lt;span style="color: #008000"&gt;// Func&amp;lt;TClass, Func&amp;lt;Arg0, Arg1..., Result&amp;gt;&amp;gt; -&amp;gt; Func&amp;lt;TClass, Result&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; arguments = lambda.Type.GetGenericArguments().ToArray();&lt;br /&gt;        arguments[arguments.Length - 1] = arguments.Last().GetGenericArguments().Last();&lt;br /&gt; &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Expression.Invoke(&lt;br /&gt;                    Expression.Lambda(&lt;br /&gt;                        lambda.Type.GetGenericTypeDefinition().MakeGenericType(arguments),&lt;br /&gt;                        VisitLambdaInvocation(lambda.Body, args),&lt;br /&gt;                        lambda.Parameters),&lt;br /&gt;                    invoke.Arguments);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    &lt;span style="color: #cc6633"&gt;#region&lt;/span&gt; MemberInfo caching&lt;br /&gt; &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; Dictionary&amp;lt;MemberInfo, QueryProperty&amp;gt; lookup = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Dictionary&amp;lt;MemberInfo, QueryProperty&amp;gt;();&lt;br /&gt; &lt;br /&gt;    &lt;span style="color: #008000"&gt;// This is not strictly needed, but adds a performance improvement.&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;// Feel free to remove this code if you think memory is more important&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; QueryProperty GetProperty(MemberInfo info)&lt;br /&gt;    {&lt;br /&gt;        QueryProperty result = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (lookup.TryGetValue(info, &lt;span style="color: #0000ff"&gt;out&lt;/span&gt; result) == &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; attribute = Attribute.GetCustomAttribute(info, &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(QueryPropertyAttribute)) &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; QueryPropertyAttribute;&lt;br /&gt; &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (attribute != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;                lookup.Add(info, result = attribute.GetProperty());&lt;br /&gt;        }&lt;br /&gt; &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; result;&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    &lt;span style="color: #cc6633"&gt;#endregion&lt;/span&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;As usual, here is the &lt;a href="http://marshall.iinet.net.au/code/QuerySpecification4.zip"&gt;sample code&lt;/a&gt; for you to experiment with yourself. &lt;br /&gt;&lt;br /&gt;I hope you've enjoyed this series, I certainly have.&amp;#160; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If I get the chance I might write a post explaining the expression parsing in detail, or the compiled queries - but till then... &lt;br /&gt;&lt;br /&gt;Cheers!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-6244597881515494393?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/6244597881515494393/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=6244597881515494393' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/6244597881515494393'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/6244597881515494393'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2008/07/advanced-domain-model-queries-using_23.html' title='Advanced Domain Model queries using Linq - Part IV'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-8149295458906973525</id><published>2008-07-17T14:22:00.004+10:00</published><updated>2008-07-17T14:33:16.824+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='linq'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Advanced Domain Model queries using Linq - Part III</title><content type='html'>I didn't intend to post so quickly after my &lt;a href="http://mathgeekcoder.blogspot.com/2008/07/advanced-domain-model-queries-using_16.html"&gt;last post&lt;/a&gt;, but some comments from &lt;a href="http://www.ubik.com.au/blog"&gt;Nick&lt;/a&gt; motivated me to try something different.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;So what's changed?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Not much.&amp;#160; Defining your query properties has changed (and obviously some implementation details).&amp;#160; All the linq syntax stuff stays the same.&lt;br /&gt;&lt;br /&gt;Here's the same Loan class, rewritten:  &lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 350px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Loan&lt;br /&gt;{&lt;br /&gt;    [OverdueFee]&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt; OverdueFee&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; OverdueFeeAttribute.Property.GetValue(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;); }&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    [IsOverdue]&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; IsOverdue&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; IsOverdueAttribute.Property.GetValue(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;); }&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    [DaysOverdue]&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; DaysOverdue&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; DaysOverdueAttribute.Property.GetValue(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;); }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;And here's our query property definition: &lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 400px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt; IsOverdueAttribute : QueryPropertyAttribute&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; IsOverdueAttribute() : &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;(Property) { }&lt;br /&gt; &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; QueryProperty&amp;lt;Loan, &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&amp;gt; Property = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; QueryProperty&amp;lt;Loan,&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&amp;gt;(&lt;br /&gt;        x =&amp;gt; (x.DateReturned == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; (DateTime.Now - x.DateBorrowed).TotalDays &amp;gt; x.LoanPeriod));&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt; OverdueFeeAttribute : QueryPropertyAttribute&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; OverdueFeeAttribute() : &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;(Property) { }&lt;br /&gt; &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; QueryProperty&amp;lt;Loan, &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;&amp;gt; Property = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; QueryProperty&amp;lt;Loan, &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;&amp;gt;(&lt;br /&gt;        x =&amp;gt; (&lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;)(x.DaysOverdue * 0.45));&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt; DaysOverdueAttribute : QueryPropertyAttribute&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; DaysOverdueAttribute() : &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;(Property) { }&lt;br /&gt; &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; QueryProperty&amp;lt;Loan, &lt;span style="color: #0000ff"&gt;double&lt;/span&gt;&amp;gt; Property = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; QueryProperty&amp;lt;Loan, &lt;span style="color: #0000ff"&gt;double&lt;/span&gt;&amp;gt;(&lt;br /&gt;        x =&amp;gt; x.IsOverdue ? (DateTime.Now - x.DateBorrowed).TotalDays - x.LoanPeriod : 0);&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;strong&gt;What's the difference?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Well, depending on your programming tastes, it's cleaner.&amp;#160; We've reduced some of the tight coupling, and we now have the ability to spread the logic (which is more suitable in certain situations).&lt;br /&gt;&lt;br /&gt;And if you're wondering why I seem to have an obsession with static members, it's mainly due to performance - and truth be told, I'm pre-optimizing here.&amp;#160; Generally I'm not such a fan... honest!&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Performance anxiety&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Speaking of performance, using Attributes has a penalty.&amp;#160; According to my tests, it's roughly 30% slower to parse the expression.&amp;#160;&amp;#160;&lt;br /&gt;&lt;br /&gt;This might sound like a lot, but we're talking about 0.37 vs 0.28 milliseconds per query here - and once you consider the database retrieval time... it's really nothing.&lt;br /&gt;&lt;br /&gt;I don't even parse the expression tree with &lt;em&gt;linq to objects&lt;/em&gt; - so no impact at all!&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Bonus code &lt;/strong&gt;(Expression Parser)&lt;br /&gt;&lt;br /&gt;Here's my expression parsing code, I know you want to see it:&lt;br /&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 300px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt; QueryPropertyEvaluator : ExpressionVisitor&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; Expression VisitMemberAccess(MemberExpression m)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (m.Expression != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; attribute = Attribute.GetCustomAttribute(m.Member, &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(QueryPropertyAttribute)) &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; QueryPropertyAttribute;&lt;br /&gt; &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (attribute != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Expression.Invoke(attribute.Property.GetExpression(), m.Expression);&lt;br /&gt;        }&lt;br /&gt; &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.VisitMemberAccess(m);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Beautiful isn't it!&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Feedback please&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;If you've been following this little series, I'd love to hear what you think of the new syntax.&lt;br /&gt;&lt;br /&gt;I'm still hesitant, since this new syntax results in more code - but I think it's a cleaner approach.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As usual, you can find the sample app &lt;a href="http://marshall.iinet.net.au/code/QuerySpecification3.zip"&gt;here&lt;/a&gt; - enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-8149295458906973525?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/8149295458906973525/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=8149295458906973525' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/8149295458906973525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/8149295458906973525'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2008/07/advanced-domain-model-queries-using_17.html' title='Advanced Domain Model queries using Linq - Part III'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-1537401647440629761</id><published>2008-07-16T17:53:00.005+10:00</published><updated>2008-07-17T14:36:08.697+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='linq'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Advanced Domain Model queries using Linq - Part II</title><content type='html'>Since my &lt;a href="http://mathgeekcoder.blogspot.com/2008/07/advanced-domain-model-queries-using.html"&gt;previous post&lt;/a&gt; I've rewritten the internals to make use of &lt;a href="http://www.albahari.com/nutshell/linqkit.html"&gt;LinqKit&lt;/a&gt; - a fantastic lightweight project.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;See the changes&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;I took my rewrite as an opportunity to support the full query syntax:  &lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; overdue = &lt;span style="color: #0000ff"&gt;from&lt;/span&gt; a &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; repository.AsQueryable()&lt;br /&gt;              &lt;span style="color: #0000ff"&gt;where&lt;/span&gt; a.IsOverdue == &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;&lt;br /&gt;              &lt;span style="color: #0000ff"&gt;select&lt;/span&gt; a.OverdueFee;&lt;br /&gt; &lt;br /&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; days = repository.AsQueryable()&lt;br /&gt;                     .Where(x =&amp;gt; x.IsOverdue)&lt;br /&gt;                     .Select(x =&amp;gt; x.DaysOverdue);&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;and added easy support for compiled queries (currently only supporting &lt;em&gt;linq to objects&lt;/em&gt; and &lt;em&gt;linq to sql&lt;/em&gt;):&lt;br /&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; query = repository.Compile(&lt;br /&gt;    source =&amp;gt; &lt;span style="color: #0000ff"&gt;from&lt;/span&gt; x &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; source&lt;br /&gt;              &lt;span style="color: #0000ff"&gt;where&lt;/span&gt; x.IsOverdue == &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;&lt;br /&gt;              &lt;span style="color: #0000ff"&gt;select&lt;/span&gt; x.OverdueFee);&lt;br /&gt; &lt;br /&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; results = repository.Execute(query);&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;I've also optimized the expression parsing (speed difference is negligible to normal queries), and I tweaked the QueryProperty construction:&lt;br /&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 230px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #cc6633"&gt;#region&lt;/span&gt; IsOverdue Property&lt;br /&gt; &lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; IsOverdue&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; IsOverdueProperty.GetValue(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;); }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; QueryProperty&amp;lt;Loan, &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&amp;gt; IsOverdueProperty = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; QueryProperty&amp;lt;Loan, &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&amp;gt;(&lt;br /&gt;    x =&amp;gt; x.IsOverdue, &lt;br /&gt;    x =&amp;gt; x.DateReturned == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; (DateTime.Now - x.DateBorrowed).TotalDays &amp;gt; x.LoanPeriod);&lt;br /&gt; &lt;br /&gt;&lt;span style="color: #cc6633"&gt;#endregion&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;The big change here is that I've added an extra parameter; a reference back to the mapping property.&lt;br /&gt;&lt;br /&gt;I'd &lt;strong&gt;really &lt;/strong&gt;like a memberof(Loan.IsOverdue) keyword style syntax in C#, but since there's not, I use this expression to grab the MemberInfo - which is used in the expression parser.&lt;br /&gt;&lt;br /&gt;It's a slight &lt;a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;DRY&lt;/a&gt; drawback, but it's a faster way than using reflection (and avoids an ugly string lookup) - and it's much faster than using attributes.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Get the code&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Most of the big changes are all implementation specific, so be sure to check out the &lt;a href="http://marshall.iinet.net.au/code/QuerySpecification2.zip"&gt;sample app&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Please let me know what you think!&lt;br /&gt;&lt;br /&gt;BTW: Joseph, I made some architectural changes to the LinqKit.ExpandableQuery stuff.&amp;#160; Externally it behaves exactly the same, but it now lets me reuse a lot more code.&lt;br /&gt;&lt;br /&gt;It's light on the comments, but I'm hoping my next post will explain myself.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ed: Continue to &lt;a href="http://mathgeekcoder.blogspot.com/2008/07/advanced-domain-model-queries-using_17.html"&gt;Part III&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-1537401647440629761?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/1537401647440629761/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=1537401647440629761' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/1537401647440629761'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/1537401647440629761'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2008/07/advanced-domain-model-queries-using_16.html' title='Advanced Domain Model queries using Linq - Part II'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-5121408089605450294</id><published>2008-07-15T11:55:00.002+10:00</published><updated>2008-07-15T11:57:36.042+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Ctrl . - My favourite shortcut</title><content type='html'>&lt;p&gt;I'm a huge keyboard shortcut fan (for a windows developer)... for common tasks it's just annoying to have to grab the mouse.   &lt;br /&gt;    &lt;br /&gt;For me, one such task was the rename / resolve support in Visual Studio:&lt;a href="http://lh4.ggpht.com/luke.jonathon.marshall/SHwDgc3uNQI/AAAAAAAAACM/FiVt3PctS98/unresolved%5B28%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="125" alt="unresolved" src="http://lh5.ggpht.com/luke.jonathon.marshall/SHwDg1c9SMI/AAAAAAAAACQ/OJqWt8jMpEk/unresolved_thumb%5B22%5D.png" width="464" border="0" /&gt;&lt;/a&gt;&amp;#160; &lt;br /&gt;Using the mouse to bring up this dialog has got to be the most frustrating task in Visual Studio.    &lt;br /&gt;    &lt;br /&gt;So much so, I refused to use it; instead opting for the right-click 'resolve' approach, or even manually typing in namespaces.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/luke.jonathon.marshall/SHwDhXDNYkI/AAAAAAAAACU/pFacWpj-Rh0/resolve%5B4%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="118" alt="resolve" src="http://lh3.ggpht.com/luke.jonathon.marshall/SHwDhyrzqBI/AAAAAAAAACY/d6ISxsoel_g/resolve_thumb%5B2%5D.png" width="464" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;A few months ago, I stumbled on &amp;quot;Ctrl .&amp;quot; and to my delight ended my coding frustration.   &lt;br /&gt;    &lt;br /&gt;I'm now more productive, less frustrated... do yourself a favour and give &amp;quot;Ctrl .&amp;quot; a go!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-5121408089605450294?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/5121408089605450294/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=5121408089605450294' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/5121408089605450294'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/5121408089605450294'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2008/07/ctrl-my-favourite-shortcut.html' title='Ctrl . - My favourite shortcut'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/luke.jonathon.marshall/SHwDg1c9SMI/AAAAAAAAACQ/OJqWt8jMpEk/s72-c/unresolved_thumb%5B22%5D.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-5253001939929266418</id><published>2008-07-07T18:21:00.005+10:00</published><updated>2008-07-16T18:07:10.510+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='linq'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Advanced Domain Model queries using Linq</title><content type='html'>I read a fantastic &lt;a href="http://www.ubik.com.au/article/named/implementing_the_specification_pattern_with_linq"&gt;blog article&lt;/a&gt; from Nick Blumhardt yesterday which kicked off some crazy ideas in my head.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The Problem&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;With the following class, I can query on &lt;strong&gt;&lt;em&gt;IsOverdue&lt;/em&gt;&lt;/strong&gt; using linq... but not using linq to sql (or linq to nhibernate).&amp;#160; How frustrating! &lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 210px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Loan&lt;br /&gt;{&lt;br /&gt;  &lt;span style="color: #008000"&gt;// Member details omitted&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; IsOverdue&lt;br /&gt;  {&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; &lt;br /&gt;    {&lt;br /&gt;       &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; DateReturned == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; &lt;br /&gt;          (DateTime.Now - DateBorrowed).TotalDays &amp;gt; LoanPeriod;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;This is a fundamental issue in relational to object mapping systems, but we can fix it using some linq trickery. &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;I think my solution is very cool, but I'm not sure how acceptable it is for a production environment.&amp;#160;&lt;br /&gt;&lt;br /&gt;Please leave feedback if you like it / makes you want to vomit.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The change&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Let's modify the Loan class implementation of &lt;strong&gt;&lt;em&gt;IsOverdue&lt;/em&gt;&lt;/strong&gt;:&lt;br /&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #cc6633"&gt;#region&lt;/span&gt; IsOverdue Property&lt;br /&gt; &lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; IsOverdue&lt;br /&gt;{&lt;br /&gt;  &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; IsOverdueProperty.GetValue(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;); }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; QueryProperty&amp;lt;Loan, &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&amp;gt; IsOverdueProperty = QueryProperty.Register&amp;lt;Loan, &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&amp;gt;(&lt;br /&gt;    x =&amp;gt; x.DateReturned == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; (DateTime.Now - x.DateBorrowed).TotalDays &amp;gt; x.LoanPeriod);&lt;br /&gt; &lt;br /&gt;&lt;span style="color: #cc6633"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Here we move the logic for &lt;strong&gt;&lt;em&gt;IsOverdue &lt;/em&gt;&lt;/strong&gt;into a separate QueryProperty member that takes care of the nasty details.&lt;br /&gt;&lt;br /&gt;Hopefully you'll agree that the code is still fairly readable, and encapsulated with all the logic still bundled inside the Loan class.&lt;br /&gt;&lt;br /&gt;By moving this logic into a lambda expression, we can now write queries for both database and object collections! e.g&lt;br /&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;// Database Access&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; db = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RepositoryDatabase&amp;lt;Loan&amp;gt;())&lt;br /&gt;  &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; overdue = db.Where(y =&amp;gt; y.IsOverdue &amp;amp;&amp;amp; y.LoanPeriod == 5);&lt;br /&gt; &lt;br /&gt;&lt;span style="color: #008000"&gt;// Collection Access&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; list = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RepositoryCollection&amp;lt;Loan&amp;gt;())&lt;br /&gt;  &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; overdue = list.Where(y =&amp;gt; y.IsOverdue &amp;amp;&amp;amp; y.LoanPeriod == 5);&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;strong&gt;More Goodness&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;When coding these query properties it can be very handy to reference other query properties. e.g.&lt;br /&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 400px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #cc6633"&gt;#region&lt;/span&gt; DaysOverdue Property&lt;br /&gt; &lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; DaysOverdue&lt;br /&gt;{&lt;br /&gt;  &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; DaysOverdueProperty.GetValue(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;); }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; QueryProperty&amp;lt;Loan, &lt;span style="color: #0000ff"&gt;double&lt;/span&gt;&amp;gt; DaysOverdueProperty = QueryProperty.Register&amp;lt;Loan, &lt;span style="color: #0000ff"&gt;double&lt;/span&gt;&amp;gt;(&lt;br /&gt;  x =&amp;gt; x.IsOverdue ? (DateTime.Now - x.DateBorrowed).TotalDays - x.LoanPeriod : 0);&lt;br /&gt; &lt;br /&gt;&lt;span style="color: #cc6633"&gt;#endregion&lt;/span&gt;&lt;br /&gt; &lt;br /&gt;&lt;span style="color: #cc6633"&gt;#region&lt;/span&gt; OverdueFee Property&lt;br /&gt; &lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt; OverdueFee&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; OverdueFeeProperty.GetValue(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;); }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; QueryProperty&amp;lt;Loan, &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;&amp;gt; OverdueFeeProperty = QueryProperty.Register&amp;lt;Loan, &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;&amp;gt;(&lt;br /&gt;  x =&amp;gt; (&lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;)(x.DaysOverdue * 0.45));&lt;br /&gt; &lt;br /&gt;&lt;span style="color: #cc6633"&gt;#endregion&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;This allows us to create very complicated queries in a very simple manner.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The Catch&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Too good to be true?&amp;#160; You're right; there's a devil in the details.&amp;#160;&lt;br /&gt;&lt;br /&gt;You might have picked it up already - how does linq interpret my query property correctly?&lt;br /&gt;&lt;br /&gt;By modifying the expression tree!&lt;br /&gt;&lt;br /&gt;My Repository class implements the Where() and translates the expression; replacing any QueryProperty references with a call to the actual lambda expression. &lt;br /&gt;&lt;br /&gt;The really ugly part is that it's a string based lookup ie. &amp;quot;&amp;lt;name&amp;gt;Property&amp;quot;.&amp;#160; Though I also check the type to be extra safe.&lt;br /&gt;&lt;br /&gt;It's really not a bad trade off, considering it's very similar to how WPF DependencyProperty's work. &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The Conclusion&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;This is a really easy and seamless way to implement custom queryable properties in your domain objects. &lt;br /&gt;&lt;br /&gt;I've only touched on a fraction of the possibilities with this technique, but it shows the power and flexibility of linq. &lt;br /&gt;&lt;br /&gt;Make sure you check out the &lt;a href="http://marshall.iinet.net.au/code/QuerySpecification.zip"&gt;sample application&lt;/a&gt; for the full code.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ed: Continue to &lt;a href="http://mathgeekcoder.blogspot.com/2008/07/advanced-domain-model-queries-using_16.html"&gt;Part II&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-5253001939929266418?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/5253001939929266418/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=5253001939929266418' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/5253001939929266418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/5253001939929266418'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2008/07/advanced-domain-model-queries-using.html' title='Advanced Domain Model queries using Linq'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-6342829650305269672</id><published>2008-06-27T16:37:00.005+10:00</published><updated>2008-06-27T17:09:29.079+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Loop optimization trickery</title><content type='html'>A while ago I was playing around with C# 3.5 lambda expressions trying to work out how it behaves with variable scope.&lt;br /&gt;&lt;br /&gt;What do you think is written to the console?&lt;br /&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 400px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Program&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;// Write number to console in worker thread&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 1; i &amp;lt; 9; i++)&lt;br /&gt;            DoLater(() =&amp;gt; Console.Write(i));&lt;br /&gt;    }&lt;br /&gt;     &lt;br /&gt;    &lt;span style="color: #008000"&gt;// Call action delegate on separate thread&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; DoLater(Action action)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;// I'm avoiding using another lambda here to simplify test&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Thread(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ParameterizedThreadStart(DoLater)).Start(action);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: #008000"&gt;// Calls the action after waiting for a second&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; DoLater(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; action)&lt;br /&gt;    {&lt;br /&gt;        Thread.Sleep(1000);&lt;br /&gt;        ((Action)action)();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;If you initially guessed (like me) that it displays the numbers 1-9 in some random order (eg. '14385726') - you'd be wrong...&amp;#160;&amp;#160; it actually produces '999999999' every time. &lt;br /&gt;&lt;br /&gt;So I cranked up &lt;a href="http://www.aisto.com/roeder/dotnet/"&gt;.net reflector&lt;/a&gt; (I love it) and had a look at my code (optimization set to .NET 1.0 - then translated by me):&lt;br /&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;{&lt;br /&gt;    AutoDelegateClass tmpVar = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; AutoDelegateClass();&lt;br /&gt;    tmpVar.i = 1;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (tmpVar.i &amp;lt; 9)&lt;br /&gt;    {&lt;br /&gt;        DoLater(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Action(tmpVar.Method));&lt;br /&gt;        tmpVar.i++;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;This is much more obvious...&amp;#160; .net optimizes the lambda expression out of the loop!&lt;br /&gt;&lt;br /&gt;Well that was unexpected, but guess what happens when I change main to this:&lt;br /&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 1; i &amp;lt; 9; i++)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; j = i;&lt;br /&gt;        DoLater(() =&amp;gt; Console.Write(j));&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;This works! ie. it &lt;strong&gt;does not&lt;/strong&gt; optimize the lambda expression out of the loop.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Although confusing at first, it actually makes a lot of sense from the compiler point of view - the initial expression doesn't actually change, since we are referencing a mutable variable... so why not optimize it?&lt;br /&gt;&lt;br /&gt;It might be convenient to turn off this optimization programmatically - kind of like a volatile keyword or something, but it's no big deal.&lt;br /&gt;&lt;br /&gt;I guess it goes to show that functional code works best with immutable data... and that reflector is way cool.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;BTW: The exact same thing occurs in foreach over a collection; and also using classes rather than structs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-6342829650305269672?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/6342829650305269672/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=6342829650305269672' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/6342829650305269672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/6342829650305269672'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2008/06/loop-optimization-trickery.html' title='Loop optimization trickery'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-6256841265691084216</id><published>2008-06-23T13:35:00.002+10:00</published><updated>2008-06-23T13:37:04.740+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='ui'/><category scheme='http://www.blogger.com/atom/ns#' term='random thoughts'/><title type='text'>UI - You don't know how much you suck</title><content type='html'>&lt;p&gt;I made a small mistake in my last post - instead of '&lt;strong&gt;do what you want&lt;/strong&gt;' what I meant to say was:     &lt;br /&gt;    &lt;br /&gt;&lt;strong&gt;Hire a damn graphic designer and buy some icons!&lt;/strong&gt;    &lt;br /&gt;    &lt;br /&gt;This is a subtle difference, but the delusion of competency is unfortunately common.&lt;a href="http://lh4.ggpht.com/luke.jonathon.marshall/SF8aENiEtxI/AAAAAAAAACE/Mn5HCLLhS-o/m-diy-disaster%5B3%5D.jpg"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="104" alt="m-diy-disaster" src="http://lh5.ggpht.com/luke.jonathon.marshall/SF8aEVL4MPI/AAAAAAAAACI/xA0aPdooMv4/m-diy-disaster_thumb%5B1%5D.jpg" width="155" align="right" border="0" /&gt;&lt;/a&gt;    &lt;br /&gt;    &lt;br /&gt;Like your home handyman disasters, the DYI attitude for user interfaces can cost you big time.    &lt;br /&gt;    &lt;br /&gt;However IT departments are usually too cheap, and some developer ego's are too big to realize that they can't do everything... thus UI abominations are created everyday.    &lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;UI development is hard, harder than most people think.&amp;#160; &lt;br /&gt;    &lt;br /&gt;The UI layer is where everything comes together, and as a result it's here you find all the issues with the underlying architecture.    &lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;If you're a UI developer - you suck, so make sure you check out the UI guidelines for your dev system (&lt;a href="http://msdn.microsoft.com/en-us/library/aa511258.aspx"&gt;Microsoft&lt;/a&gt;, &lt;a href="http://developer.apple.com/documentation/UserExperience/Conceptual/AppleHIGuidelines/XHIGIntro/chapter_1_section_1.html"&gt;Apple&lt;/a&gt;, &lt;a href="http://developer.gnome.org/projects/gup/hig/"&gt;Gnome&lt;/a&gt; or &lt;a href="http://developer.kde.org/documentation/design/ui/"&gt;KDE&lt;/a&gt;).    &lt;br /&gt;    &lt;br /&gt;If you're &lt;strong&gt;not &lt;/strong&gt;a &lt;strong&gt;UI&lt;/strong&gt; developer; shut up, fix your code and give the UI guys a break.    &lt;br /&gt;    &lt;br /&gt;Oh, and good luck!    &lt;br /&gt;    &lt;br /&gt;Disclaimer: I've done both jobs, so I suck twice as much.    &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-6256841265691084216?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/6256841265691084216/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=6256841265691084216' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/6256841265691084216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/6256841265691084216'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2008/06/ui-you-don-know-how-much-you-suck.html' title='UI - You don&amp;#39;t know how much you suck'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/luke.jonathon.marshall/SF8aEVL4MPI/AAAAAAAAACI/xA0aPdooMv4/s72-c/m-diy-disaster_thumb%5B1%5D.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-24930619613561944</id><published>2008-04-22T10:38:00.002+10:00</published><updated>2008-04-22T11:16:44.978+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='ui'/><title type='text'>UI - You can't please everyone</title><content type='html'>Although it's difficult to create good UI, it doesn't mean that bad UI is easy - in fact some people go to great lengths to produce &lt;a href="http://mike-austin.com/blog/uploaded_images/badui2-747337.jpg"&gt;bad UI&lt;/a&gt;.  &lt;br /&gt;&lt;br /&gt;That said, good UI simply boils down to:  &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Intuitive&lt;/strong&gt;, &lt;strong&gt;Pretty &lt;/strong&gt;and &lt;strong&gt;Performant&lt;/strong&gt; - in a combination that &lt;em&gt;targets&lt;/em&gt; the intended user.  &lt;br /&gt;&lt;br /&gt;eg. A programmer is going to prefer performance over pretty, and a hairdresser might prefer pretty over intuitive... but you still need all three for a good user experience.  &lt;br /&gt;&lt;br /&gt;If you don't have access to your user (and that's generally the case), just pretend that you are the user. &lt;br /&gt;&lt;br /&gt;If you wouldn't use your own app; that's a good sign of bad UI.  &lt;br /&gt;&lt;br /&gt;&lt;em&gt;In the end, you can't please everyone - so please yourself, then at least one person is happy.&lt;/em&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-24930619613561944?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/24930619613561944/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=24930619613561944' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/24930619613561944'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/24930619613561944'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2008/04/ui-you-can-please-everyone.html' title='UI - You can&amp;#39;t please everyone'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-3156359093141842738</id><published>2008-02-20T12:35:00.003+10:00</published><updated>2008-02-20T12:45:47.027+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maths'/><category scheme='http://www.blogger.com/atom/ns#' term='f#'/><title type='text'>Six Percent Genius</title><content type='html'>&lt;a href="http://projecteuler.net/"&gt;Project Euler&lt;/a&gt; (pronounced "Oiler") provides a number (~182) of challenging math/programming problems... which is a fantastic environment to play with F#!&lt;br /&gt;&lt;br /&gt;I've only completed 6% of the questions but I've already learnt a lot. (F# is huge)&lt;br /&gt;&lt;br /&gt;If you have some free time (or get bored during your compiles), I'd definitely recommend having a go - in your own language of choice of course!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-3156359093141842738?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/3156359093141842738/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=3156359093141842738' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/3156359093141842738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/3156359093141842738'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2008/02/six-percent-genius.html' title='Six Percent Genius'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-110315237694075072</id><published>2008-01-15T12:20:00.000+10:00</published><updated>2008-01-16T08:47:50.197+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maths'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Deriving Miss Daisy</title><content type='html'>As I've mentioned &lt;a href="http://mathgeekcoder.blogspot.com/2007/10/f-is-so-pass.html"&gt;previously&lt;/a&gt;, I'm slowly reading through &lt;a href="http://mitpress.mit.edu/sicp/"&gt;SICP&lt;/a&gt; - it's an amazing book and reading it has been a humbling experience.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;'Geeking' Out&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;I completely geeked out reading one example on functional derivatives.&amp;#160; (Take a math expression as a parameter and return the derivative as an expression)&lt;br /&gt;&lt;br /&gt;It's in the first chapter, and they use this to implement Newton's Method -&amp;gt; to then implement a Sqrt function!&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Approximate Derivative&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;After I picked my brain off the floor, I decided to have a crack at implementing derivatives in C# using lambda expressions:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh6.google.com/luke.jonathon.marshall/R4wp_m7jS8I/AAAAAAAAABc/sw3GrVZk36Q/derivative%5B9%5D"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="43" alt="derivative" src="http://lh4.google.com/luke.jonathon.marshall/R4wqAG7jS9I/AAAAAAAAABk/SjXj2WUGwJQ/derivative_thumb%5B7%5D" width="236" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Using the formula of a derivative (above), we can simply code an approximate derivative (below):&lt;br /&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4; max-height: 200px"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;Func&amp;lt;&lt;span style="color: #0000ff"&gt;double&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;double&lt;/span&gt;&amp;gt; Approximate(Func&amp;lt;&lt;span style="color: #0000ff"&gt;double&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;double&lt;/span&gt;&amp;gt; f)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; h = 0.0001;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; a =&amp;gt; ((f(a + h) - f(a)) / h);&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;strong&gt;Symbolic Derivation&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Easy huh!&amp;#160; So for fun I decided to use linq expression trees to derive algebraically.&lt;br /&gt;&lt;br /&gt;It's easy to get an expression tree in C# - simply use the Expression&amp;lt;&amp;gt; type.&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4; max-height: 200px"&gt;&lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;Func&amp;lt;&lt;span style="color: #0000ff"&gt;double&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;double&lt;/span&gt;&amp;gt; Derive(Expression&amp;lt;Func&amp;lt;&lt;span style="color: #0000ff"&gt;double&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;double&lt;/span&gt;&amp;gt;&amp;gt; e)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; lambda = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Derivative().Eval(e) &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; LambdaExpression;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; (Func&amp;lt;&lt;span style="color: #0000ff"&gt;double&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;double&lt;/span&gt;&amp;gt;) lambda.Compile();&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;I parse the expression tree using &lt;a href="http://blogs.msdn.com/mattwar/archive/2007/07/31/linq-building-an-iqueryable-provider-part-ii.aspx"&gt;Matt Warren's ExpressionVisitor&lt;/a&gt; class - and using the &lt;a href="http://en.wikipedia.org/wiki/Differentiation_rules"&gt;basic rules of Derivation&lt;/a&gt; (Constant, Product and Quotient rules) we get: &lt;br /&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4; max-height: 200px"&gt;  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Derivative : ExpressionVisitor&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Expression Eval(Expression exp)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Visit(Evaluator.PartialEval(exp));&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; Expression VisitBinary(BinaryExpression b)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;// Product Rule: (fg)' = f'g + fg' &lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (b.NodeType == ExpressionType.Multiply)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Expression.Add(&lt;br /&gt;                Expression.Multiply(Eval(b.Left), b.Right),&lt;br /&gt;                Expression.Multiply(b.Left, Eval(b.Right)));&lt;br /&gt;        }&lt;br /&gt;    &lt;br /&gt;        &lt;span style="color: #008000"&gt;// Quotient Rule: (f/g)' = (f'g - fg') / (g*g)&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (b.NodeType == ExpressionType.Divide)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Expression.Divide(&lt;br /&gt;                Expression.Subtract(&lt;br /&gt;                    Expression.Multiply(Eval(b.Left), b.Right),&lt;br /&gt;                    Expression.Multiply(b.Left, Eval(b.Right))),&lt;br /&gt;                Expression.Multiply(b.Right, b.Right));&lt;br /&gt;        }&lt;br /&gt;    &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.VisitBinary(b);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: #008000"&gt;// Parameter Derivation: f(x)' = 1&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; Expression VisitParameter(ParameterExpression p)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Expression.Constant(1.0);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: #008000"&gt;// Constant Rule f(a)' = 0&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; Expression VisitConstant(ConstantExpression c)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Expression.Constant(0.0);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;strong&gt;Wrapping it up&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;To quickly finish this long blog post, here's the usage code:&lt;br /&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4; max-height: 200px"&gt;  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;// f(x * x * x)' = 3 * x * x&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; approx = Approximate(x =&amp;gt; x * x * x);&lt;br /&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; derive = Derive(x =&amp;gt; x * x * x);&lt;br /&gt; &lt;br /&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; y1 = approx(1); &lt;span style="color: #008000"&gt;// 3.0000300001109532&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; y2 = derive(1); &lt;span style="color: #008000"&gt;// 3.0&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;And there it is!&amp;#160; Useful? maybe not.&amp;#160; Fun? Definitely!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-110315237694075072?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/110315237694075072/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=110315237694075072' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/110315237694075072'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/110315237694075072'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2008/01/deriving-miss-daisy.html' title='Deriving Miss Daisy'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-4995550660211140536</id><published>2008-01-07T10:21:00.000+10:00</published><updated>2008-01-07T11:27:02.367+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='random thoughts'/><title type='text'>The 'Y' in Blog</title><content type='html'>It's quite demoralizing when you consider how much you don't know.  I am continually reminded that I underestimate it's sheer quantity...  it's a sad realization.&lt;br /&gt;&lt;br /&gt;Since there is &lt;span style="font-weight:bold;"&gt;so&lt;/span&gt; much already written by people more knowledgeable and intelligent than myself, why do I write?&lt;br /&gt;&lt;br /&gt;Well, I started this blog to show my appreciation, and hopefully to contribute something back to the development community. &lt;br /&gt;&lt;br /&gt;So kudos to all of you... keep sharing the love (of maths &amp; programming)!&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Associate with people who are searching for answers, avoid those who have found them.&lt;/blockquote&gt;&lt;br /&gt;Happy New Year!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-4995550660211140536?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/4995550660211140536/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=4995550660211140536' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/4995550660211140536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/4995550660211140536'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2008/01/y-in-blog.html' title='The &apos;Y&apos; in Blog'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-6674075491643891705</id><published>2007-12-07T15:57:00.000+10:00</published><updated>2008-01-09T09:28:26.533+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linq'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>MSDTC + Linq to Sql Update</title><content type='html'>When I was writing my &lt;a href="http://mathgeekcoder.blogspot.com/2007/11/avoiding-msdtc-with-linq-to-sql.html"&gt;previous article&lt;/a&gt;, I was keenly aware that it had it's limitations.  One in particular was using an already open DataContext.&lt;br /&gt;&lt;br /&gt;Take the following code:&lt;br /&gt;&lt;div style="background-color: #f4f4f4; font-family: Consolas, 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt;  border: solid 1px gray; cursor: text; margin: 20px 0px 10px 0px; max-height: 230px; overflow: auto; padding: 4px 4px 4px 4px; width: 97.5%;"&gt;&lt;pre style="background-color: #f4f4f4; font-family: Consolas, 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt;  border-style: none; color: black; overflow: visible; padding: 0px 0px 0px 0px; width: 100%; margin: 0em;"&gt;&lt;span style="color: #008000;"&gt;// Create outside TransactionScope&lt;/span&gt;&lt;br /&gt;var c1 = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; UserDataContext();&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; (var scope = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; TransactionScope())&lt;br /&gt;{&lt;br /&gt;    c1.Users.ToList();&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #008000;"&gt;// This will promote to MSDTC&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; (var c2 = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; UserDataContext())&lt;br /&gt;        c2.Users.ToList();&lt;br /&gt;&lt;br /&gt;    scope.Complete();&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;Since it was created outside the TransactionScope I have no way of automatically sharing these connections.&lt;br /&gt;&lt;br /&gt;To help solve this problem (cleanly) I added a SharedConnectionScope class and a UseExistingConnection call (shown below) - both take an existing DataContext.&lt;br /&gt;&lt;div style="background-color: #f4f4f4; font-family: Consolas, 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt;  border: solid 1px gray; cursor: text; margin: 20px 0px 10px 0px; max-height: 260px; overflow: auto; padding: 4px 4px 4px 4px; width: 97.5%;"&gt;&lt;pre style="background-color: #f4f4f4; font-family: Consolas, 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt;  border-style: none; color: black; overflow: visible; padding: 0px 0px 0px 0px; width: 100%; margin: 0em;"&gt;&lt;span style="color: #008000;"&gt;// Create outside TransactionScope&lt;/span&gt;&lt;br /&gt;var c1 = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; UserDataContext();&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; (var scope = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; TransactionScope())&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; (SharedDataContext.UseExistingConnection(c1))&lt;br /&gt;{&lt;br /&gt;    c1.Users.ToList();&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #008000;"&gt;// This will share existing connection&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; (var c2 = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; UserDataContext())&lt;br /&gt;        c2.Users.ToList();&lt;br /&gt;&lt;br /&gt;    scope.Complete();&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Caveat: It only works with one 'external' connection, but that's still better than none.  &lt;br /&gt;&lt;br /&gt;You can &lt;a href="http://marshall.iinet.net.au/code/LinqTransaction_II.zip" onclick="pageTracker._trackPageview('/LinqTransaction_II.zip');"&gt;grab the updated code here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-6674075491643891705?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/6674075491643891705/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=6674075491643891705' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/6674075491643891705'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/6674075491643891705'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2007/12/msdtc-linq-to-sql-update.html' title='MSDTC + Linq to Sql Update'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-6455526192908104664</id><published>2007-12-06T11:44:00.001+10:00</published><updated>2008-01-09T09:29:49.331+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='linq'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Quick Application - Tickle Me Pink</title><content type='html'>&lt;p&gt;&lt;a href="http://lh4.google.com/luke.jonathon.marshall/R1dT7B-8-nI/AAAAAAAAABM/-Gj3js7Pu5s/colors%5B7%5D"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="colors" src="http://lh3.google.com/luke.jonathon.marshall/R1dT7x-8-oI/AAAAAAAAABU/dW3eItBnaqM/colors_thumb%5B3%5D" width="100" align="right" border="0" /&gt;&lt;/a&gt;I do all my WPF coding in straight XAML, and for my prototypes I like to use the standard .Net colors. &lt;/p&gt;  &lt;p&gt;So instead of playing a fun colorname -&amp;gt; color guessing game, I thought I'd have some fun and whip up this tiny color app (it's ridiculously easy in WPF).&amp;#160; &lt;/p&gt;  &lt;p&gt;The &lt;a href="http://marshall.iinet.net.au/code/Colors.zip" onclick="pageTracker._trackPageview('/Colors.zip');"&gt;following code&lt;/a&gt; is the entire application, it combines WPF, reflection, Linq and Anonymous Types.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;br /&gt;&lt;br /&gt;UPDATE: Adjusted layout to look better in google reader.&lt;br /&gt;&lt;br /&gt;&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4; max-height: 330px"&gt;   &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Window&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x:Class&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Colors.ColorWindow&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Title&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Colors&amp;quot;&lt;/span&gt; &lt;br /&gt;    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #ff0000"&gt;xmlns:x&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #ff0000"&gt;xmlns:my&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;clr-namespace:Colors&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;WindowStyle&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;ToolWindow&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;500&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;200&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Window.Resources&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;DataTemplate&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x:Key&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;ColorTemplate&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;StackPanel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Orientation&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Horizontal&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Border&lt;/span&gt; &lt;span style="color: #ff0000"&gt;BorderBrush&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Black&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;BorderThickness&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;30&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;30&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;10&amp;quot;&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #ff0000"&gt;Background&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;{Binding Brush}&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ToolTip&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;{Binding Brush.Color}&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBlock&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;{Binding Name}&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;VerticalAlignment&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Center&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;StackPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;DataTemplate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Window.Resources&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ListBox&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x:Name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;colors&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ItemTemplate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;{StaticResource ColorTemplate}&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Window&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4; max-height: 240px"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;partial&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ColorWindow : Window&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ColorWindow()&lt;br /&gt;    {&lt;br /&gt;        InitializeComponent();&lt;br /&gt;&lt;br /&gt;        colors.ItemsSource = &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(Brushes)&lt;br /&gt;            .GetProperties(BindingFlags.Static | BindingFlags.Public)&lt;br /&gt;            .Select(x =&amp;gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; { &lt;br /&gt;                                Name = x.Name, &lt;br /&gt;                                Brush = x.GetValue(&lt;span style="color: #0000ff"&gt;null&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;                             });&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-6455526192908104664?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/6455526192908104664/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=6455526192908104664' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/6455526192908104664'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/6455526192908104664'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2007/12/quick-application-tickle-me-pink.html' title='Quick Application - Tickle Me Pink'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-8668032847566770240</id><published>2007-12-04T18:59:00.000+10:00</published><updated>2007-12-04T11:58:47.997+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><title type='text'>DataModel-View-ViewModel</title><content type='html'>WPF changed the rules for UI best practice, but it didn't update the book. &lt;br /&gt;&lt;br /&gt;With all the new and improved DataBinding and Command features - a new set of patterns have emerged, including a recommended pattern called &lt;a href="http://blogs.sqlxml.org/bryantlikes/archive/2006/09/27/WPF-Patterns.aspx"&gt;DataModel-View-ViewModel&lt;/a&gt; (DM-V-VM).&lt;br /&gt;&lt;br /&gt;At a conceptual level this pattern looks fantastic – but there are issues... namely it doesn’t work for non-trivial scenarios.&lt;br /&gt;&lt;br /&gt;Rather than a boring high level rant, I'll use boring examples to explain why:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Cannot support events&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The recommended approach is to use DataTemplates and Commands - but DataTempates cannot handle events, and the command system is not extensive enough (eg. doesn't support mouse clicks).&lt;br /&gt;&lt;br /&gt;Supporting events requires using code behind; which means using at least a UserControl base class.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;No Keyboard support for Standard Commands&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Dan Crevier and John Gossman don't mention the standard Commands, instead opting to create their own – not because it's better practice, but it's easier to demonstrate.&lt;br /&gt;&lt;br /&gt;Their suggested approach uses CommandParameter bindings on the buttons, which only works with OnClick (i.e when the shortcut Key is pressed "null" is passed through).&lt;br /&gt;&lt;br /&gt;Since the InputBindings.KeyBinding.CommandParameter does not support DataBinding - supporting the keyboard (and still using commands) means we can't use CommandParameters.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;UI support breaks abstraction&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Say that we want to delete all the selected items from a list; this means storing a list of items in the ViewModel (since we not using CommandParameters), which we then bind from our View.&lt;br /&gt;&lt;br /&gt;But this is purely for UI logic rather than business logic!  &lt;br /&gt;&lt;br /&gt;Complicated scenarios might need multiple properties - and since the binding is not clearly defined, it will introduce bugs.&lt;br /&gt;&lt;br /&gt;The abstraction is now broken, so let's just move our ViewModel into the code behind.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Unit testing the UI logic now not easy&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;No kidding, that's why we initially moved the code into the ViewModel!&lt;br /&gt;&lt;br /&gt;All of the real logic should be implemented in the data bound objects or by a class separate to the UI.  These classes are unit testable, but the UI integration is not.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Aren't we back to where we started?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Not quite, WPF's new style allows us to develop a cleaner system than the days of WinForms and MFC - and while there's not a published best practice for it, it doesn't mean that it doesn't exist.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;UI programming is hard, especially since it looks so easy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-8668032847566770240?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/8668032847566770240/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=8668032847566770240' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/8668032847566770240'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/8668032847566770240'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2007/12/datamodel-view-viewmodel.html' title='DataModel-View-ViewModel'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-6502354090884493458</id><published>2007-12-03T07:34:00.000+10:00</published><updated>2008-01-09T09:31:08.665+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linq'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Avoiding MSDTC with Linq to Sql</title><content type='html'>Now &lt;a href="http://blah.winsmarts.com/2006/06/03/a-quick-primer-on-systemtransactions.aspx"&gt;MSDTC&lt;/a&gt; is not evil; it's just overkill &lt;span style="font-style:italic;"&gt;when it isn't needed&lt;/span&gt;.  It slows performance, increases complexity and requires client side configuration... and it can activate when you least expect it.&lt;br /&gt;&lt;br /&gt;Take the following code:&lt;br /&gt;&lt;div style="background-color: #f4f4f4; font-family: Consolas, 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt;  border: solid 1px gray; cursor: text; margin: 20px 0px 10px 0px; max-height: 325px; overflow: auto; padding: 4px 4px 4px 4px; width: 97.5%;"&gt;&lt;pre style="background-color: #f4f4f4; font-family: Consolas, 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt;  border-style: none; color: black; overflow: visible; padding: 0px 0px 0px 0px; width: 100%; margin: 0em;"&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; CreateUsers()&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; (var scope = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; TransactionScope(TransactionScopeOption.Required))&lt;br /&gt;    {&lt;br /&gt;        CreateUser(&lt;span style="color: #006080;"&gt;"Fred"&lt;/span&gt;);&lt;br /&gt;        CreateUser(&lt;span style="color: #006080;"&gt;"Joe"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;        scope.Complete();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; CreateUser(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; name)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; (var context = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; UserDataContext())&lt;br /&gt;    {&lt;br /&gt;        context.Users.InsertOnSubmit(&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; User { name = name });&lt;br /&gt;        context.SubmitChanges();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;This code uses the recommended (and very helpful) TransactionScope class - and unfortunately invokes MSDTC.&lt;br /&gt;&lt;br /&gt;Since we're using separate instances of UserDataContext this creates separate database connections - and causes TransactionScope to "&lt;a href="http://blogs.msdn.com/florinlazar/archive/2005/05/12/416805.aspx"&gt;promote&lt;/a&gt;" the transaction to require MSDTC.&lt;br /&gt;&lt;br /&gt;Avoiding this is as simple as sharing the database connection - after all, it is the same database - but passing database connections to sub methods gets ugly really quick.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;My Solution&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To solve this problem in a cleaner manner, I wrote a Transaction Resource Manager - which works behind the scenes and makes the above code work without change.&lt;br /&gt;&lt;br /&gt;It simply shares database connections across the instances (only within a transaction).  It's thread safe, and easy to integrate - simply change the DataContext base class in the dbml designer.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_xTtnD_Ymy78/R0_Bt_5LiYI/AAAAAAAAAAU/j9pOXuW2ff0/s1600-R/linqtransaction.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_xTtnD_Ymy78/R0_Bt_5LiYI/AAAAAAAAAAU/NBorCoh6PMM/s320/linqtransaction.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5138538695842564482" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://marshall.iinet.net.au/code/LinqTransaction.zip" onclick="pageTracker._trackPageview('/LinqTransaction.zip');"&gt;Grab the code&lt;/a&gt; and check it out.  There's an example program and a whole slew of unit tests (around 275 - testing the various permutations of &lt;a href="http://www.pluralsight.com/blogs/jimjohn/archive/2005/06/18/11451.aspx"&gt;nested TransactionScopes&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Kudos to Nick Guerrea's &lt;a href="http://blogs.msdn.com/nicholg/archive/2006/06/04/617466.aspx"&gt;Weak Dictionary&lt;/a&gt; - which I use to weakly track the transactions and share the connections.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Same Solution for other Scenarios&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There are other scenarios where this problem arises:&lt;br /&gt;&lt;br /&gt;Say you've got a database with many tables (or a plug-in system that shares a database) - a modular approach uses multiple DataContext classes.&lt;br /&gt;&lt;br /&gt;Our problem occurs when you need to modify tables from different DataContexts within a single transaction.&lt;br /&gt;&lt;br /&gt;Thankfully, the root cause is still the same and our solution solves these cases as well.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This has been a great learning experience for me, and I must say that the Transaction Resource Managers are very interesting (might even make a good alternate &lt;a href="http://ubik.com.au/article/named/andreis_scopeguard_for_c"&gt;ScopeGuard implementation&lt;/a&gt;?)&lt;br /&gt;&lt;br /&gt;EDIT: See &lt;a href="http://mathgeekcoder.blogspot.com/2007/12/msdtc-linq-to-sql-update.html"&gt;updated article&lt;/a&gt; for extra goodness.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-6502354090884493458?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/6502354090884493458/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=6502354090884493458' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/6502354090884493458'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/6502354090884493458'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2007/11/avoiding-msdtc-with-linq-to-sql.html' title='Avoiding MSDTC with Linq to Sql'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_xTtnD_Ymy78/R0_Bt_5LiYI/AAAAAAAAAAU/NBorCoh6PMM/s72-c/linqtransaction.jpg' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-1304652691394598643</id><published>2007-11-28T14:08:00.000+10:00</published><updated>2007-11-28T14:31:26.897+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Quick Tip - Read Only Automatic Properties</title><content type='html'>This is a simple little trick, which I only discovered a few weeks ago.&lt;br /&gt;&lt;br /&gt;In the past providing public "read only" access to a member would look something like:&lt;br /&gt;&lt;div style="background-color: #f4f4f4; font-family: Consolas, 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt;  border: solid 1px gray; cursor: text; margin: 20px 0px 10px 0px; max-height: 200px; overflow: auto; padding: 4px 4px 4px 4px; width: 97.5%;"&gt;&lt;pre style="background-color: #f4f4f4; font-family: Consolas, 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt;  border-style: none; color: black; overflow: visible; padding: 0px 0px 0px 0px; width: 100%; margin: 0em;"&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; connection;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; Connection&lt;br /&gt;{ &lt;br /&gt;    get { &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; connection; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;With Automatic Properties in C# 3.5 the code becomes:&lt;br /&gt;&lt;div style="background-color: #f4f4f4; font-family: Consolas, 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt;  border: solid 1px gray; cursor: text; margin: 20px 0px 10px 0px; max-height: 200px; overflow: auto; padding: 4px 4px 4px 4px; width: 97.5%;"&gt;&lt;pre style="background-color: #f4f4f4; font-family: Consolas, 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt;  border-style: none; color: black; overflow: visible; padding: 0px 0px 0px 0px; width: 100%; margin: 0em;"&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; Connection { get; &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; set; }&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;The neat trick is the access modifier (private) next to the set.  This allow you to internally modify the member, while publicly providing "read only" access.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-1304652691394598643?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/1304652691394598643/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=1304652691394598643' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/1304652691394598643'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/1304652691394598643'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2007/11/quick-tip-read-only-automatic.html' title='Quick Tip - Read Only Automatic Properties'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-5375047681297565011</id><published>2007-11-26T14:52:00.001+10:00</published><updated>2008-01-09T09:25:42.789+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='xceed'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>VS2008 RTM Update</title><content type='html'>I have updated all the downloadable code to compile with the RTM release of VS2008.&lt;br /&gt;&lt;br /&gt;It's not a big change, so I'll use this blog entry to update my Xceed &lt;-&gt; Linq code.  I've fixed some minor bugs, improved performance a lot and added better linq syntax support.&lt;br /&gt;&lt;br /&gt;So if you're using the code, it'd be a &lt;a href="http://marshall.iinet.net.au/code/LinqDataGrid_V.zip" onclick="pageTracker._trackPageview('/LinqDataGrid_V.zip');"&gt;good idea to update&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-5375047681297565011?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/5375047681297565011/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=5375047681297565011' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/5375047681297565011'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/5375047681297565011'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2007/11/vs2008-rtm-update.html' title='VS2008 RTM Update'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-5584240398991618148</id><published>2007-11-19T15:35:00.001+10:00</published><updated>2007-11-19T16:01:56.239+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linq'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>IEnumerable Joy - Batch / Split</title><content type='html'>&lt;p&gt;I was inspired by my good friend Nick's latest blog entry &lt;a href="http://www.ubik.com.au/article/named/return_of_the_batch_enumerable"&gt;Return of the Batch Enumerable&lt;/a&gt;.&amp;#160; &lt;/p&gt;  &lt;p&gt;Here he demonstrates a neat idea of using extension methods and yield to split an IEnumerable into arbitrary batches.&lt;/p&gt;  &lt;p&gt;My version is slightly less efficient, but treats the batches as separate lazy collections - so you can use it on multiple threads etc.&lt;/p&gt;  &lt;p&gt;I've also added a Split extension, which I'll describe - but first, the code!&lt;/p&gt;  &lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 270px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; height: 250px; background-color: #f4f4f4"&gt;   &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; InBatchesExtension&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; IEnumerable&amp;lt;IEnumerable&amp;lt;T&amp;gt;&amp;gt; InBatches&amp;lt;T&amp;gt;(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; source, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; batchSize)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (IEnumerable&amp;lt;T&amp;gt; s = source; s.Any(); s = s.Skip(batchSize))&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;yield&lt;/span&gt; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; s.Take(batchSize);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; IEnumerable&amp;lt;IEnumerable&amp;lt;T&amp;gt;&amp;gt; Split&amp;lt;T&amp;gt;(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; source, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; items)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; items; ++i)&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;yield&lt;/span&gt; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; source.Where((x, index) =&amp;gt; (index % items) == i);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The InBatches returns the same output as Nicks:&lt;/p&gt;&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt; &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;Batch: 1 2 3&lt;br /&gt;Batch: 4 5 6&lt;br /&gt;Batch: 7&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And the Split batches the output across the collections:&lt;/p&gt;&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;Batch: 1 4 7&lt;br /&gt;Batch: 2 5&lt;br /&gt;Batch: 3 6&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;So this gives you 2 different batch splitting methods for a generic enumerable.&lt;/p&gt;&lt;p&gt;I love this stuff.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-5584240398991618148?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/5584240398991618148/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=5584240398991618148' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/5584240398991618148'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/5584240398991618148'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2007/11/ienumerable-joy-batch-split.html' title='IEnumerable Joy - Batch / Split'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-6682708247515028996</id><published>2007-11-13T10:29:00.000+10:00</published><updated>2007-11-13T10:30:41.745+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linq'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Wield the Yield</title><content type='html'>Recently I've noticed an IO pattern emerging combining yield and linq; a powerful and efficient mechanism to read data.&lt;br /&gt;&lt;br /&gt;Check the following code:  We safely open a file (with the using statement), and yield the results with a loop.&lt;br /&gt;&lt;div style="background-color: #f4f4f4; font-family: Consolas, 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt;  border: solid 1px gray; cursor: text; margin: 20px 0px 10px 0px; max-height: 200px; overflow: auto; padding: 4px 4px 4px 4px; width: 97.5%;"&gt;&lt;pre style="background-color: #f4f4f4; font-family: Consolas, 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt;  border-style: none; color: black; overflow: visible; padding: 0px 0px 0px 0px; width: 100%; margin: 0em;"&gt;IEnumerable&amp;lt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&amp;gt; ReadFile(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; filename)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; (StreamReader reader = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; StreamReader(File.OpenRead(filename)))&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;while&lt;/span&gt; (reader.EndOfStream == &lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;)&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;yield&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; reader.ReadLine();&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;This simple (and beautiful) code allows us to treat a file like an array of strings - which becomes very powerful when coupled with linq.&lt;br /&gt;&lt;div style="background-color: #f4f4f4; font-family: Consolas, 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt;  border: solid 1px gray; cursor: text; margin: 20px 0px 10px 0px; max-height: 200px; overflow: auto; padding: 4px 4px 4px 4px; width: 97.5%;"&gt;&lt;pre style="background-color: #f4f4f4; font-family: Consolas, 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt;  border-style: none; color: black; overflow: visible; padding: 0px 0px 0px 0px; width: 100%; margin: 0em;"&gt;&lt;span style="color: #008000;"&gt;// Contrived example - How many file lines refer to "fred"?&lt;/span&gt;&lt;br /&gt;var result = ReadFile(&lt;span style="color: #006080;"&gt;"file.txt"&lt;/span&gt;).Where(x =&amp;gt; x.Contains(&lt;span style="color: #006080;"&gt;"fred"&lt;/span&gt;)).Count();&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;I'm sure this same pattern could also be applied to other data retrieval methods, eg algorithm calculation (prime numbers, Fibonacci, etc), network communication (message queue) and even as an abstraction over asynchronous data methods.&lt;br /&gt;&lt;br /&gt;Yield provides a lazy enumeration (doesn't execute unless needed) so the solution is generic and efficient - I like it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-6682708247515028996?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/6682708247515028996/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=6682708247515028996' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/6682708247515028996'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/6682708247515028996'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2007/11/wield-yield.html' title='Wield the Yield'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-8981071359133626472</id><published>2007-11-05T08:10:00.000+10:00</published><updated>2007-11-09T22:07:59.186+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maths'/><category scheme='http://www.blogger.com/atom/ns#' term='linq'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>n! - let me count the ways</title><content type='html'>The other day I had an interesting discrete maths assignment question involving permutations - so I decided to codify it.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&amp;quot;How many ways can six people (Josh, Toby, CJ, Sam, Leo &amp;amp; Donna) sit, if Josh must sit to the left of Leo and to the right of Sam.&amp;quot;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Now the astute reader will immediately recognize the answer to be 2 * (4! + 3!3!) = 120; but to be sure I wanted to double check this via C#. (I'm keen to redo this in F# too)&lt;br /&gt;&lt;br /&gt;My solution was a quick hack, and is by no means &amp;quot;the best way&amp;quot; - but using linq it sure looks pretty.&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: #f4f4f4; font-family: Consolas, 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt;  border: solid 1px gray; cursor: text; margin: 20px 0px 10px 0px; max-height: 600px; overflow: auto; padding: 4px 4px 4px 4px; width: 97.5%;"&gt;&lt;pre style="background-color: #f4f4f4; font-family: Consolas, 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt;  border-style: none; color: black; overflow: visible; padding: 0px 0px 0px 0px; width: 100%; margin: 0em;"&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; IEnumerable&amp;lt;List&amp;lt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&amp;gt;&amp;gt; Permutate(IEnumerable&amp;lt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&amp;gt; people, &lt;br /&gt;                                               IEnumerable&amp;lt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&amp;gt; current)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000;"&gt;// Get remaining people and recurse&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt; (var person &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; people.Where(x =&amp;gt; current.Contains(x) == &lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;))&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt; (var result &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; Permutate(people, current.Concat(&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] { person })))&lt;br /&gt;                &lt;span style="color: #0000ff;"&gt;yield&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; result;&lt;br /&gt; &lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (current.Count() == people.Count())&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;yield&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; current.ToList();&lt;br /&gt;    }&lt;br /&gt;   &lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] people = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] { &lt;span style="color: #006080;"&gt;"Josh"&lt;/span&gt;, &lt;span style="color: #006080;"&gt;"Toby"&lt;/span&gt;, &lt;span style="color: #006080;"&gt;"CJ"&lt;/span&gt;, &lt;span style="color: #006080;"&gt;"Sam"&lt;/span&gt;, &lt;span style="color: #006080;"&gt;"Leo"&lt;/span&gt;, &lt;span style="color: #006080;"&gt;"Donna"&lt;/span&gt; };&lt;br /&gt;  &lt;br /&gt;        var result = Permutate(people, &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] { }).ToList();&lt;br /&gt;   &lt;br /&gt;        &lt;span style="color: #008000;"&gt;// Josh sits to the left of Leo&lt;/span&gt;&lt;br /&gt;        var Josh_Leo = result.Where(r =&amp;gt;&lt;br /&gt;            r.FindIndex(x =&amp;gt; x == &lt;span style="color: #006080;"&gt;"Josh"&lt;/span&gt;) &amp;lt; r.FindIndex(x =&amp;gt; x == &lt;span style="color: #006080;"&gt;"Leo"&lt;/span&gt;));&lt;br /&gt; &lt;br /&gt;        &lt;span style="color: #008000;"&gt;// Josh sits to the right of Sam&lt;/span&gt;&lt;br /&gt;        var Sam_Josh = Josh_Leo.Where(r =&amp;gt;&lt;br /&gt;            r.FindIndex(x =&amp;gt; x == &lt;span style="color: #006080;"&gt;"Sam"&lt;/span&gt;) &amp;lt; r.FindIndex(x =&amp;gt; x == &lt;span style="color: #006080;"&gt;"Josh"&lt;/span&gt;));&lt;br /&gt; &lt;br /&gt;        var count = Sam_Josh.Count();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;This simple example shows why I'm a such fan of linq in C# - the pre-linq code for this certainly wouldn't be as eloquent.&lt;br /&gt;&lt;br /&gt;Oh, and it also shows why I'm a fan of maths... it's much more efficient to just to calculate the factorials.&lt;br /&gt;&lt;br /&gt;Update: Formatting code in a blog sure is a pain!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-8981071359133626472?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/8981071359133626472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=8981071359133626472' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/8981071359133626472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/8981071359133626472'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2007/11/n-let-me-count-ways.html' title='n! - let me count the ways'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-4549956580947258020</id><published>2007-10-30T08:51:00.000+10:00</published><updated>2007-10-30T12:38:09.727+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='f#'/><title type='text'>F# is so Passé</title><content type='html'>Lately I've been trying to juggle learning a mix of technology.  WPF, .net 3.5 (linq), maths, F#...  Sometimes I feel like I have &lt;a href="http://www.digidave.org/adventures_in_freelancing/2007/01/internet_multit_1.html"&gt;Internet Multitasking Syndrome&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Although Internet Multitasking Syndrome is not a known medical disorder (I just made it up five minutes ago), it is not uncommon for people to become so immersed in their online activities that their cognitive abilities wane.&lt;br /&gt;&lt;br /&gt;After hours starring at a screen, flipping between web pages and information outlets, people can develop a feeling of anxiety, stress and a decrease in mental performance, said John Suler, author of The Psychology of Cyberspace.  &lt;br /&gt;&lt;br /&gt;"There are limits to how much information one person can process," he continued.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;I started learning about a little known language called F# a couple of months ago, where I read most of the &lt;a href="http://www.amazon.com/dp/1590597575?tag=strangelights-20&amp;camp=14573&amp;creative=327641&amp;linkCode=as1&amp;creativeASIN=1590597575&amp;adid=194NXGA12FFNG06A7BDQ&amp;"&gt;Foundations of F#&lt;/a&gt; book over a rather intense week.  &lt;br /&gt;&lt;br /&gt;Since then I've dropped the ball...  there's just too much to learn within our software field.&lt;br /&gt;&lt;br /&gt;I'm keen to get back into it, as F#'s functional principles are very appealing to me.  There's a sense of power and elitism playing with such a language.  It's close to it's mathematical roots, and has the potential to create highly concurrent systems.&lt;br /&gt;&lt;br /&gt;These things are addictive for software engineers.  Power and elitism - it's why C/C++ are so popular and &lt;a href="http://clintonforbes.blogspot.com/2007/02/why-dont-visual-basic-programmers-get.html"&gt;why VB programmers get no respect&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now that F# is an &lt;a href="http://blogs.msdn.com/somasegar/archive/2007/10/17/f-a-functional-programming-language.aspx"&gt;official MS language&lt;/a&gt;, it's becoming quite popular.  While this is fantastic for the language - a small selfish part of me wants to keep it for myself.  I don't want it to become 'common' and spoilt by countless bad programmers writing spaghetti code.&lt;br /&gt;&lt;br /&gt;Unfortunately this also includes me - so to avoid becoming an Italian Chef, I'm planning to read &lt;a href="http://mitpress.mit.edu/sicp/"&gt;Structure and Interpretation of Computer Programs&lt;/a&gt; during my holidays.  I've heard this is a classic book covering functional programming (in scheme).&lt;br /&gt;&lt;br /&gt;Wish me luck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-4549956580947258020?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/4549956580947258020/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=4549956580947258020' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/4549956580947258020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/4549956580947258020'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2007/10/f-is-so-pass.html' title='F# is so Passé'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-4259851647379584001</id><published>2007-10-10T14:28:00.000+10:00</published><updated>2007-10-11T08:53:40.470+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='motorbikes'/><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><title type='text'>Death Trap</title><content type='html'>When I first started riding my motorbike I became much more aware of my environment... and not in a pleasant way.  After coming out of my metal cocoon (car), everything became a threat and I felt fully exposed to the world.&lt;br /&gt;&lt;br /&gt;It's with good reason too; I live in beautiful Queensland where &lt;a href="http://www.transport.qld.gov.au/Home/Safety/Road/"&gt;every week 1 rider dies and 15 are injured&lt;/a&gt;.  And I don't need a maths degree to know that the statistics are against me.&lt;br /&gt;&lt;br /&gt;Even still I love riding my bike, it got me out of my comfort zone and I have a new perspective, and a new sense of freedom and opportunity.&lt;br /&gt;&lt;br /&gt;So here comes the clichéd analogy to programming.... Our comfort zone is our greatest death trap.&lt;br /&gt;&lt;br /&gt;Our industry moves far too quickly learn everything, so it's an easy trap to become stagnant with familiar technology.&lt;br /&gt;&lt;br /&gt;We've all been victim's of stagnancy at some point, but tragically some developers spiral down until they &lt;b&gt;feel&lt;/b&gt; so far behind there's no point playing catch up.   &lt;br /&gt;&lt;br /&gt;Then they're stuck working with an obscure, unsupported technology - or they get promoted into management.&lt;br /&gt;&lt;br /&gt;Others are trapped by their language of choice.  I met a guy just recently who, with great passion, thought 'C' was the language for everything.  Web apps, database apps... everything.&lt;br /&gt;&lt;br /&gt;I felt for this guy, because I've been there before... and it's utter madness.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It takes effort and it's painful to learn new things.  There's also a high risk that what you learn is completely redundant... but while it's important to pick your technology carefully - it's better to learn something than nothing at all.&lt;br /&gt;&lt;br /&gt;My challenge is to never stop learning; it's not without risk or effort - but the rewards of freedom and perspective are invaluable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-4259851647379584001?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/4259851647379584001/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=4259851647379584001' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/4259851647379584001'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/4259851647379584001'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2007/10/death-trap.html' title='Death Trap'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-5311762546068395854</id><published>2007-10-02T08:02:00.001+10:00</published><updated>2007-10-02T09:35:29.134+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maths'/><title type='text'>I don't want to be a Maths Teacher</title><content type='html'>Before I started my maths degree I braced myself for the inevitable question "why maths?"&lt;br /&gt;&lt;br /&gt;That's okay, maths isn't everyones favorite subject - but as it turns out the more popular question is "do you want to be a Maths teacher?"... &lt;br /&gt;&lt;br /&gt;No!&lt;br /&gt;&lt;br /&gt;Don't get me wrong, I have no problems with teaching, in fact it might be cool to be a lecturer one day... but it makes me sad that &lt;b&gt;people think learning maths is only good for teaching maths&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;It's like the definition of Recursion: see Recursion; a tragic cycle of futility; a perpetual motion machine that affects nothing and goes nowhere.&lt;br /&gt;&lt;br /&gt;No!&lt;br /&gt;&lt;br /&gt;I want to shout out from the roof tops - don't people realize that maths is the basis of all technology and human advancement?  &lt;br /&gt;&lt;br /&gt;Economically, math brings order to chaos.  The steady job, the home (or mortgage), even food on the table and clothes on our backs - thank maths.  Too melodramatic?  Google the &lt;a href="http://www.google.com.au/search?q=great+depression"&gt;Great Depression&lt;/a&gt; sometime.&lt;br /&gt;&lt;br /&gt;Math heals us when we are sick.  Statistical drug trials determine what medicine works, mathematical models of the human body are used by doctors and physiotherapists to determine better techniques for recovery.&lt;br /&gt;&lt;br /&gt;I won't even get started on computers or civil construction.&lt;br /&gt;&lt;br /&gt;Above all, maths is &lt;a href="http://en.wikipedia.org/wiki/Mathematical_beauty"&gt;eloquent, philosophical and beautiful&lt;/a&gt;.  It changes your perceptions and makes you appreciate everyday life even more.&lt;br /&gt;&lt;br /&gt;&amp;lt;/rant&amp;gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-5311762546068395854?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/5311762546068395854/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=5311762546068395854' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/5311762546068395854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/5311762546068395854'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2007/10/i-dont-want-to-be-maths-teacher.html' title='I don&apos;t want to be a Maths Teacher'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-175457923832292744</id><published>2007-09-27T13:26:00.000+10:00</published><updated>2008-01-09T09:32:54.015+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='xceed'/><category scheme='http://www.blogger.com/atom/ns#' term='linq'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Updatable, inheritable, WPF bounded Linq queries</title><content type='html'>This is part 4 of my "binding Linq to Xceed's data grid" blog series; however I've changed direction dramatically.&lt;br /&gt;&lt;br /&gt;Skipping the details, heres the code binding to a linq query:&lt;pre style="line-height: normal;border: 1px solid #808000;background-color: #FFFFCC;"&gt;&lt;br /&gt;  users.LinqContext = new UserDataContext();&lt;br /&gt;  &lt;br /&gt;  users.ItemsSource = from i&lt;br /&gt;                      in users.DataSource&amp;lt;User&amp;gt;() &lt;br /&gt;                      select i;&lt;br /&gt; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And this code fully supports inserts/updates/deletes.&lt;br /&gt;&lt;br /&gt;The implementation lives inside the DataSource&amp;lt;User&amp;gt;() call.  This devious character returns a reference to a IBindingList (which supports the table modifications) and implements IQueryable (to support linq queries).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What about inheritance?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Imagine you had a sub class called SuperUser; if you've played with linq inheritance you'll know that you have to use the base type User to actually do anything.  It's kind of a pain, and you get real friendly with the .OfType&amp;lt;&amp;gt;() call.&lt;br /&gt;&lt;br /&gt;So here's the code again, this time selecting all SuperUsers.&lt;br /&gt;&lt;br /&gt;&lt;pre style="line-height: normal;border: 1px solid #808000;background-color: #FFFFCC;"&gt;&lt;br /&gt;  users.ItemsSource = from i &lt;br /&gt;                      in users.DataSource&amp;lt;User, SuperUser&amp;gt;() &lt;br /&gt;                      select i;&lt;br /&gt; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;Can I use .Take(x)?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;As far as I can tell, &lt;i&gt;all&lt;/i&gt; the standard linq statements are supported (including aggregate operators).  I haven't looked into partial classes and anonymous types, though I doubt they'd work well.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I won't go into the laborious details of how it's all implemented, just know that it's been fun playing with linq expression trees and writing my own IQueryProvider.&lt;br /&gt;&lt;br /&gt;If you are interested, the code can be found &lt;a href="http://marshall.iinet.net.au/code/LinqDataGrid_IV.zip" onclick="pageTracker._trackPageview('/LinqDataGrid_IV.zip');"&gt;here.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I haven't seen anything quite like this out there, so if you have some opinions - I'd love to hear some feedback.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-175457923832292744?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/175457923832292744/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=175457923832292744' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/175457923832292744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/175457923832292744'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2007/09/updatable-inheritable-wpf-bounded-linq.html' title='Updatable, inheritable, WPF bounded Linq queries'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-396763209398317784</id><published>2007-09-24T10:25:00.000+10:00</published><updated>2007-10-02T08:01:58.771+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='linq'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Linq Table and GetNewBindingList()</title><content type='html'>While I'm talking about binding linq data tables to WPF, I should mention the simplest method, namely Table&lt;TEntity&gt;.GetNewBindingList();&lt;br /&gt;&lt;br /&gt;This method allows you to add/insert/update (even with Xceed's grid) quite easily, but does not save implicitly, ie. you have to manage it yourself.&lt;br /&gt;&lt;br /&gt;If you prefer to batch up all your changes and save en mass at a special point (this is a common UI pattern) - then this might be a great solution for you.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;One issue with with approach however, is that it only supports the whole table, ie. not based on queries.  This might be fine if you are using the WPF's data filters, but it's not an optimal result with large amounts of data.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I'm planning to investigate these two aspects in the near future, and hopefully I'll find an elegant solution.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-396763209398317784?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/396763209398317784/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=396763209398317784' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/396763209398317784'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/396763209398317784'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2007/09/linq-table-and-getnewbindinglist.html' title='Linq Table and GetNewBindingList()'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-4556937451927340780</id><published>2007-09-21T12:15:00.000+10:00</published><updated>2008-01-09T09:33:32.672+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='xceed'/><category scheme='http://www.blogger.com/atom/ns#' term='linq'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Linq with Xceed's WPF Grid - Part III - Hooking up the Delete</title><content type='html'>One of the under appreciated features of WPF is its Command support.  This feature allows you to hook up events in a more abstract and loosely coupled way; with a great collection of common actions provided by default.&lt;br /&gt;&lt;br /&gt;To hook up delete functionality from Xceed's data grid to a Linq data table, I took advantage of these Command gems and as you will see, they make things very easy to use.&lt;br /&gt;&lt;br /&gt;The provided ApplicationCommands.Delete command, comes with a localized string ("Delete") and associated key bindings ("Del" Key).&lt;br /&gt;&lt;br /&gt;Handling this command in the LinqGrid is as simple as calling the following in the initialization routines:&lt;br /&gt;&lt;pre style="line-height: normal;border: 1px solid #808000;background-color: #FFFFCC;"&gt;&lt;br /&gt;CommandBindings.Add(new CommandBinding(ApplicationCommands.Delete, &lt;br /&gt;  OnDeleteCommand, OnCanDeleteCommand));&lt;br /&gt; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Implementing the OnCanDeleteCommand to return true, if any items are selected and the OnDeleteCommand to delete the selected items, and it's done!  Well almost.&lt;br /&gt;&lt;br /&gt;Automatically deleting the selected items (with the "Del" key) without any warning is usually not the best behaviour, so I implemented a RoutedEvent called PreviewDelete, which allows you to show a message box and/or cancel the delete.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Show me the XAML&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Another great benefit of using Commands is the ability to bind other UI elements as the action co-coordinator for the command. i.e Buttons, Context Menus, etc.&lt;br /&gt;&lt;br /&gt;Not only is this clean and easy, but it also has built in routines to control the IsEnabled state. ie. Button is disabled if you cannot currently delete.&lt;br /&gt;&lt;br /&gt;&lt;pre style="line-height: normal;border: 1px solid #808000;background-color: #FFFFCC;"&gt;&lt;br /&gt;&amp;lt;Button Command="Delete" &lt;br /&gt;        CommandTarget="{Binding ElementName=users}" &lt;br /&gt;        Content="{Binding Command.Text, RelativeSource={RelativeSource self}}" /&amp;gt;&lt;br /&gt; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The "Command" is quite simply a reference to the ApplicationCommands.Delete command, while the "CommandTarget" is the name I gave to my LinqGrid.&lt;br /&gt;&lt;br /&gt;The unfortunately long "Content" attribute is the Buttons label, bound to the Command itself.  Remember how I said the provided commands have localized names... this is how you access them in XAML.  Thankfully, this is also purely optional.&lt;br /&gt;&lt;br /&gt;This is all you need to do.  When the button is pressed, the Command is fired and our LinqGrid performs the delete, first checking with PreviewDelete for its permission.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://marshall.iinet.net.au/code/LinqDataGrid_III.zip" onclick="pageTracker._trackPageview('/LinqDataGrid_III.zip');"&gt;Download the sample solution for the full code.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-4556937451927340780?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/4556937451927340780/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=4556937451927340780' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/4556937451927340780'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/4556937451927340780'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2007/09/linq-with-xceeds-wpf-grid-part-iii.html' title='Linq with Xceed&apos;s WPF Grid - Part III - Hooking up the Delete'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-4496463731892298217</id><published>2007-09-21T09:00:00.000+10:00</published><updated>2008-01-09T09:34:22.298+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='xceed'/><category scheme='http://www.blogger.com/atom/ns#' term='linq'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Linq with Xceed's WPF Grid - Part II (and a half)</title><content type='html'>An excellent suggestion was raised from my last post (thanks Marcus), which is to make the Linq DataContext a property on the LinqGrid.&lt;br /&gt;&lt;br /&gt;This way the LinqRow can access it via it's parent, rather than via the singleton (which is bad practice in my book).&lt;br /&gt;&lt;br /&gt;I've put all this code in a solution (includes sample database and all), so I'll let the code speak for itself.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://marshall.iinet.net.au/code/LinqDataGrid.zip" onclick="pageTracker._trackPageview('/LinqDataGrid.zip');"&gt;Download Sample Solution&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-4496463731892298217?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/4496463731892298217/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=4496463731892298217' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/4496463731892298217'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/4496463731892298217'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2007/09/linq-with-xceeds-wpf-grid-part-ii-and.html' title='Linq with Xceed&apos;s WPF Grid - Part II (and a half)'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-7036144381474369479</id><published>2007-09-20T10:58:00.000+10:00</published><updated>2007-11-26T15:20:24.712+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='xceed'/><category scheme='http://www.blogger.com/atom/ns#' term='linq'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Linq with Xceed's WPF Grid - Part II</title><content type='html'>In my first post I showed a handy binding class that wraps around your linq data tables, now I'm going to show some handy changes to Xceed's data grid, to complete the linq binding.&lt;br /&gt;&lt;br /&gt;My main problem with the data grid, is there isn't any good place to commit a transaction after editing a row.&lt;br /&gt;&lt;br /&gt;To fix this, we can provide our own DataRow class which handles the SubmitChanges() when a row is dirty.&lt;br /&gt;&lt;br /&gt;Update: Modified code to use IsDirty flag. Note that IsDirty is reset to false in base.EndEdit().&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: 'Courier New', Courier, monospace;background-color: #FFFFCC;border: 1px solid #808000"&gt;&lt;br /&gt; class LinqRow : DataRow&lt;br /&gt; {&lt;br /&gt;   public override void EndEdit()&lt;br /&gt;   {&lt;br /&gt;     if (IsDirty == true)&lt;br /&gt;       DataSource.Context.SubmitChanges();&lt;br /&gt;   &lt;br /&gt;     base.EndEdit();&lt;br /&gt;   }&lt;br /&gt; }&lt;br /&gt;  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To make the DataGridControl aware of our new DataRow class, we need to derive and override the GetContainerForItemOverride() method.&lt;br /&gt;&lt;pre style="font-family: 'Courier New', Courier, monospace;background-color: #FFFFCC;border: 1px solid #808000"&gt;&lt;br /&gt; class LinqGrid : DataGridControl&lt;br /&gt; {&lt;br /&gt;   protected override DependencyObject &lt;br /&gt;       GetContainerForItemOverride()&lt;br /&gt;   {&lt;br /&gt;     return new LinqRow();&lt;br /&gt;   }&lt;br /&gt;  &lt;br /&gt;   protected override void OnInitialized(EventArgs e)&lt;br /&gt;   {&lt;br /&gt;     base.OnInitialized(e);&lt;br /&gt;  &lt;br /&gt;     if (View == null)&lt;br /&gt;     {&lt;br /&gt;       View = new TableView();&lt;br /&gt;       AdjustHeadersFooters();&lt;br /&gt;     }&lt;br /&gt;   }&lt;br /&gt;  &lt;br /&gt;   private void AdjustHeadersFooters()&lt;br /&gt;   {&lt;br /&gt;     // Show / hide the element base&lt;br /&gt;     View.FixedHeaders.Clear();&lt;br /&gt;     View.Headers.Clear();&lt;br /&gt;  &lt;br /&gt;     // Add a ColumnManagerRow&lt;br /&gt;     DataTemplate columnTemplate = new DataTemplate();&lt;br /&gt;     columnTemplate.VisualTree = &lt;br /&gt;       new FrameworkElementFactory(typeof(ColumnManagerRow));&lt;br /&gt;     View.FixedHeaders.Add(columnTemplate);&lt;br /&gt;  &lt;br /&gt;     // Add the insertion row&lt;br /&gt;     DataTemplate insertTemplate = new DataTemplate();&lt;br /&gt;     insertTemplate.VisualTree = &lt;br /&gt;       new FrameworkElementFactory(typeof(InsertionRow));&lt;br /&gt;     View.FixedHeaders.Add(insertTemplate);&lt;br /&gt;   }&lt;br /&gt; }&lt;br /&gt;  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Insertion Row&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;You may have noticed the AdjustHeadersFooters call in the class above, this code removes the GroupBy control and adds in the Insertion row by default.  The GroupBy control is cool, but I rarely use it.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Putting it together&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Instead of using the DataGridControl in your xaml file, simply use the LinqGrid.&lt;br /&gt;&lt;br /&gt;In my next few posts I'll discuss hooking up the delete, sorting and filtering, and how to use the linq queries instead of the whole table.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-7036144381474369479?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/7036144381474369479/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=7036144381474369479' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/7036144381474369479'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/7036144381474369479'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2007/09/linq-with-xceeds-wpf-grid-part-ii.html' title='Linq with Xceed&apos;s WPF Grid - Part II'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6184851556979812172.post-826397200593256796</id><published>2007-09-20T09:52:00.000+10:00</published><updated>2007-11-26T15:20:35.564+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='xceed'/><category scheme='http://www.blogger.com/atom/ns#' term='linq'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Linq with Xceed's WPF Grid</title><content type='html'>&lt;p style="margin-bottom: 4px"&gt;Binding a read only Linq data table to Xceed's WPF data grid couldn't be easier, but things get a little trickier when you want insert/delete/update functionality.&lt;br /&gt;&lt;br /&gt;The general recommendation (from Xceed's samples) is to implement a derived IBindingList collection class to provide the behaviour yourself.&lt;br /&gt;&lt;br /&gt;Sounds like a lot of work to do something simple, especially if you want to bind to a lot of different objects - so here's a generic one I've prepared.&lt;br /&gt;&lt;br /&gt;BTW: I haven't seen any articles on the web regarding best practice with this, so I'd love any comments if there is a better way.&lt;/p&gt;&lt;br /&gt;&lt;pre style="line-height: normal;border: 1px solid #808000;background-color: #FFFFCC;"&gt;&lt;br /&gt;  class LinqList&amp;lt;T&amp;gt; : BindingList&amp;lt;T&amp;gt;&lt;br /&gt;  {&lt;br /&gt;    ITable table = null;&lt;br /&gt;    &lt;br /&gt;    public LinqList(ITable table)&lt;br /&gt;      : base(table.OfType&amp;lt;T&amp;gt;().ToList())&lt;br /&gt;    {&lt;br /&gt;      this.table = table;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    protected override object AddNewCore()&lt;br /&gt;    {&lt;br /&gt;      T item = (T)base.AddNewCore();&lt;br /&gt;    &lt;br /&gt;      if (table != null)&lt;br /&gt;        table.Add(item);&lt;br /&gt;     &lt;br /&gt;      return item;&lt;br /&gt;    }&lt;br /&gt;     &lt;br /&gt;    public override void EndNew(int itemIndex)&lt;br /&gt;    {&lt;br /&gt;      base.EndNew(itemIndex);&lt;br /&gt;    &lt;br /&gt;      if (itemIndex &gt;= 0)&lt;br /&gt;        DataSource.Context.SubmitChanges();&lt;br /&gt;    }&lt;br /&gt;  &lt;br /&gt;    protected override void RemoveItem(int index)&lt;br /&gt;    {&lt;br /&gt;      if (table != null)&lt;br /&gt;        table.Remove(this[index]);&lt;br /&gt;     &lt;br /&gt;       base.RemoveItem(index);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;   &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;My first code draft uses the BindingList as a base class (to avoid implementing everything myself) and takes a Linq data table as a constructor parameter.&lt;br /&gt;&lt;br /&gt;Notice the OfType() call in the constructor, this provides basic support for inheritance with Linq, but more on that in a later post.&lt;br /&gt;&lt;br /&gt;I use a singleton to store my Linq data context (DataSource.Context) to call SubmitChanges() after adding a new item.&lt;/p&gt;&lt;br /&gt;&lt;pre style="line-height: normal;border: 1px solid #808000;background-color: #FFFFCC;"&gt;&lt;br /&gt;  static class DataSource&lt;br /&gt;  {&lt;br /&gt;    static DataSource()&lt;br /&gt;    {&lt;br /&gt;      DataSource.Context = new MyDataContext();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    static public MyDataContext Context { get; set; }&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;b&gt;Binding to Xceed&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Simply bind an instance of this class to your data grid, and you're almost set!&lt;br /&gt;&lt;br /&gt;See Part II for some changes that need to be made to the Xceed grid, to make this binding easier.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6184851556979812172-826397200593256796?l=mathgeekcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mathgeekcoder.blogspot.com/feeds/826397200593256796/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6184851556979812172&amp;postID=826397200593256796' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/826397200593256796'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6184851556979812172/posts/default/826397200593256796'/><link rel='alternate' type='text/html' href='http://mathgeekcoder.blogspot.com/2007/09/linq-with-xceeds-wpf-grid.html' title='Linq with Xceed&apos;s WPF Grid'/><author><name>Luke Marshall</name><uri>http://www.blogger.com/profile/11665669405673984228</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry></feed>
