<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>The Wayward WebLog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/mattwar/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/mattwar/feed.xml</link>
    <description>Oh, what a tangled web</description>
    <lastBuildDate>Tue, 22 Aug 2017 21:27:05 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>The Precious</title>
      <link>https://docs.microsoft.com/archive/blogs/mattwar/the-precious</link>
      <pubDate>Thu, 20 Oct 2011 12:01:00 GMT</pubDate>
      <dc:creator><![CDATA[Matt Warren - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mattwar/2011/10/20/the-precious/</guid>
      <description><![CDATA[When the light broke in from a crack in the bunker ceiling, I was not alarmed. I knew it would...]]></description>
      <content:encoded><![CDATA[<p>When the light broke in from a crack in the bunker ceiling, I was not alarmed. I knew it would inevitably come to this, that I could not stay holed up forever. Eventually they would find me. I thought about what this day would be like, off and on, for many years, wondering how it would play out. Would they come in force and drag me out? Maybe they would let me walk out on my own.</p>
<p>The footsteps overhead for the last hour gave them away, so I was not only ready, I actually had time to clean up, what little I could do in that dank hell hole. I skittered around straightening the few items I had, a tattered blanket and a musty pillow, though never more than an arms reach away from the device. I knew they would want to see it. It was after all what they were here for. I had kept it from them for years, doing everything I could to keep it secret, keep it safe. But the draw was too great. They could sense it no matter where I hid. It was only a matter of time.</p>
<p>The first one through was just a soldier. He came down on a tether with a light beaming from his helmet. I sat as calmly as I could on my solitary chair, but still my hands shook and my left foot jittered. He had his automatic rifle trained on me when he spoke.</p>
<p>&ldquo;Wayward?&rdquo; he said. Like I could have been anyone else. I did not reply, and he did not wait for one. &ldquo;It&rsquo;s him,&rdquo; he called upward, which led to a lot more scuffling and shouts.</p>
<p>The next down was a man in a business suit, followed&nbsp;by two others in street clothes.&nbsp; As the first two struggled to free themselves from the straps, the last one in sneakers and sporting a neck beard simply walked forward into the blue glow, pulling the ropes with him as he went.</p>
<p>&ldquo;Is this it?&rdquo; he said, looking away from me, into the device.</p>
<p>&ldquo;Yes.&rdquo;</p>
<p>&ldquo;All of it?&rdquo;</p>
<p>&ldquo;Yes.&rdquo;</p>
<p>His fingers reached forward and caressed the metallic exterior. It was cold to the touch no matter how hotly it burned inside. When the smile finally grew on his face, I knew he was gone.</p>
<p>&ldquo;But what is it?&rdquo; asked the suit, still unraveling his tie.</p>
<p>I just sat there and smiled nervously. The neck-beard knew everything now.</p>
<p>&ldquo;Syntax trees,&rdquo; he said, his eyes wide. &ldquo;I see syntax trees.&rdquo;</p>
<p>&hellip;</p>
<p>And that&rsquo;s how Project Roslyn CTP came to see the light of day, and I was released from my four years of seclusion.</p>
<p>Discover the precious. <a title="http://msdn.microsoft.com/en-us/roslyn" href="http://msdn.microsoft.com/en-us/roslyn">http://msdn.microsoft.com/en-us/roslyn</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Ominous Post</title>
      <link>https://docs.microsoft.com/archive/blogs/mattwar/ominous-post</link>
      <pubDate>Tue, 18 Oct 2011 15:17:19 GMT</pubDate>
      <dc:creator><![CDATA[Matt Warren - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mattwar/2011/10/18/ominous-post/</guid>
      <description><![CDATA[Something is coming.]]></description>
      <content:encoded><![CDATA[<p>Something is coming.</p>]]></content:encoded>
    </item>
    <item>
      <title>Elegance in Asynchrony</title>
      <link>https://docs.microsoft.com/archive/blogs/mattwar/elegance-in-asynchrony</link>
      <pubDate>Tue, 02 Nov 2010 23:15:00 GMT</pubDate>
      <dc:creator><![CDATA[Matt Warren - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mattwar/2010/11/02/elegance-in-asynchrony/</guid>
      <description><![CDATA[&nbsp;
It&rsquo;s been a long time since I&rsquo;ve put finger to keyboard and
typed out a post on...]]></description>
      <content:encoded><![CDATA[<p>&nbsp;</p>
<p class="MsoNormal">It&rsquo;s been a long time since I&rsquo;ve put finger to keyboard and
typed out a post on this here Wayward Weblog, an artifact of the ancient web
1.1, where men were men and posts were posts, and men posted nonsense into the amorphous
ether of the intertubes, hoping beyond hope that somehow, somewhere, someone
out there might follow its link and indulge in the inanity of a lone stranger&rsquo;s
train of thought.<span>&nbsp; </span>You might have wondered what happened.<span>&nbsp; </span>Did the Wayward drop off the planet?<span>&nbsp; </span>Or did he emigrate to the same future that
has so captivated the rest of the known universe? Did he switch to Twitter? Is
there a feed out there that encompasses the boldness that once was <i>The</i> <i>Weblog</i>?<span>&nbsp; </span>Or did he just switch to Facebook and is only
posting sumptuous morsels of enlightenment to his vast inner circle of friends?
And why weren&rsquo;t you friended? Who does this guy think he is?</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">No need to fret. Nothing so sinister has come to pass. You
would indeed all be friended by the Great Wayward himself had he the nerve to
actually book his own face, or the chutzpah to become one of the droves of twitterpaters
drowning the web in scrawls of cryptic blurbs and emoticons.<span>&nbsp; </span>But alas, a non-social cretin like the
Wayward does not change his habits even when granted a tech-laden alternative
interface to reality. The world of hyper-salivating coolness that has overtaken
so many has simply passed him by.</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">The real truth is that I&rsquo;m so anti-social that without constant
reminder that the world outside my office exists, I tend to forget everything
about it. It used to take extreme doses of overly caffeinated beverages to perk
my interest in the outer realms, the hallways and other peoples&rsquo; doors, something
that would give me a buzz and bad case of the shakes, anxiously rousing me from
my chair and sending me wandering dazedly around the building, frenetically bumping
into walls, tripping over chairs. Sometimes, if the planets aligned and the
conditions were just right, I might have found myself interacting with actual other
people. Back in the time of Jolt cola I got so wired I blacked out. I&rsquo;m not
really sure what happened, though I did get written up on a HR violation. The
lawyers won&rsquo;t let me talk about it anymore. Needless to say, those black days
are gone and will never be repeated; especially since I&rsquo;ve been off the caffeine.</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">So you can see, it&rsquo;s really not you, it&rsquo;s me, honestly. Without
the personality altering drugs, I&rsquo;m hopelessly lost in the only bit of reality
that captivates me; my code. Without survival instinct buried deep within my
brain and, of course, hunger signals I would not know when to leave and go
home.<span>&nbsp; </span>It would just be my code, day in
day out, my internal world of organizing bits into blobs, refactoring hacks
into tweeks and spewing forth all that is holy, the unquestioned word of the
Wayward.</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">Which makes it extremely out of the ordinary for me be
writing this now, far outside my comfort zone. Something tripped the switch and
sent me mousing outside my code editor and into the bleak wasteland of the syntactically
challenged word processor to type up this non-executable diatribe. You see,
something extraordinary happened. Something so beyond fantastic, I could no
longer stay focused on the screen of scintillating source in front of me. <span>&nbsp;</span></p>
<p class="MsoNormal"><span><br /></span></p>
<p class="MsoNormal">As it turns out, and to my utter astonishment, somebody else&rsquo;s
code was better.</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">And not just a little bit better; gobstoppingly better, from
coding cowboy coolness to cold cognitive bliss.</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">Last week at the PDC we released the Async CTP (community
technology preview) for C# and VB.<span>&nbsp; </span>It&rsquo;s
got this really nifty feature that turns otherwise horrendous gobbledygook of
callback nastiness into nice legible, linear source code, so you can actually
write asynchronous code as if it were synchronous; no muss, no fuss.</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">But I don&rsquo;t really need to tell you about this, as you&rsquo;ve
certainly read umpteen other blogs and news articles already that have either
confounded you with a bazillion examples or threatened you with what the code
would have otherwise looked like, the kinds of software geek horrors reserved
for Halloween night obfuscation contests.</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">We&rsquo;ve all been there, right?</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">Of course, this wasn&rsquo;t news to me.<span>&nbsp; </span>I had been in the thick of it for a long
time.<span>&nbsp; </span>Talking about asynchronous programming
was always just enough inducement to get me out from in front of my PC and into
a conference room.<span>&nbsp; </span>It wasn&rsquo;t the asynchrony
itself or the cutesy new keywords, or the magic rewrite that&rsquo;s kind of like
iterators and kind of not.<span>&nbsp; </span>It wasn&rsquo;t the
stack spilling or intricate details of exception handling that lead me to this
degree of engagement.</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">It wasn&rsquo;t the async feature at all.<span>&nbsp; </span>It was one of the samples.</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">You see, while I had been long involved in the design I&rsquo;d
never much paid attention to the periphery.<span>&nbsp;
</span>Until the CTP released, I had never took much notice in the samples the
others were busily compiling.<span>&nbsp;</span></p>
<p class="MsoNormal"><span><br /></span></p>
<p class="MsoNormal">Yet when I did, I found one sample that completely embodied
the elegance and beauty of the underlying asynchrony itself.<span>&nbsp; </span>It was and is so profoundly tied to the deep
concept that I don&rsquo;t think any other example could ever match it.</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">I&rsquo;m sure you are oozing with curiosity so I&rsquo;ll let you in on
the secret.<span>&nbsp; </span>It&rsquo;s the &lsquo;Dining Philosophers&rsquo;
sample. Go ahead and pull that one up out of the CTP and take a look at the
source.<span>&nbsp; </span>I&rsquo;ll wait.<span>&nbsp; </span>You&rsquo;ll probably see where I&rsquo;m coming from and
where I&rsquo;m going just by ogling the text, but let me explain anyway.</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">The Dining Philosophers problem is a classic computer
science problem that involves finding a process by which a group of
self-serving windbags can all sit down at a table and share a meal without
anyone starving. You&rsquo;d think that such highly educated folks would not need help
in such a matter, but in fact they do, since they are seldom in agreement and
are often focused on talking more than anything else that they seldom take the
time to even order their food, let alone realize there are not enough forks to
go around. Eggheads like me find it a grand pastime to imaging different
variations of forcing the gaggle to agree on how to accomplish this and there
are many interesting and elegant solutions.</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">For me, however, the asynchronous sample is by far the most
interesting and the most elegant.<span>&nbsp; </span>It&rsquo;s
not because the new language feature makes the code vastly simpler than it
would otherwise have been, allowing it to please the eyes and hearts of
software enthusiasts of all ilk.<span>&nbsp; </span>The
true elegance is not even readily apparent in the source itself.<span>&nbsp; </span>It&rsquo;s more both at a meta level and an
implementation level that the magnificence of the asynchrony feature really
shines through.<span>&nbsp; </span>You might not even notice
it unless you have the kind of background in both the Dining Philophers problem
and the CTP that I have, so I forgive you if you are still puzzled at this
point.</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">You see, the compiler rewrites the cutesy new asynchrony operator
into a few more explicit operations that harness the true power.<span>&nbsp; </span>You will see it right away if and when you
either decode the IL or manually translate it in your head.<span>&nbsp; </span>The very first thing that happens is the
compiler generates a call to &lsquo;GetAWaiter&rsquo;, and this alone has an immediate and
dramatic impact for the dining philosophers.<span>&nbsp;</span></p>
<p class="MsoNormal"><span><br /></span></p>
<p class="MsoNormal">After all, once you&rsquo;ve gotten a waiter, the problem about
too few forks simply solves itself.</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">I&rsquo;ll go back to my code now.</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Building a LINQ IQueryable Provider – Part XVII (IQToolkit 0.17)</title>
      <link>https://docs.microsoft.com/archive/blogs/mattwar/building-a-linq-iqueryable-provider-part-xvii-iqtoolkit-0-17</link>
      <pubDate>Tue, 09 Feb 2010 15:53:00 GMT</pubDate>
      <dc:creator><![CDATA[Matt Warren - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mattwar/2010/02/09/building-a-linq-iqueryable-provider-part-xvii-iqtoolkit-0-17/</guid>
      <description><![CDATA[This is the seventeenth in a series of posts on how to build a LINQ IQueryable provider. If you...]]></description>
      <content:encoded><![CDATA[<P>This is the <EM>seventeenth </EM>in a series of posts on how to build a LINQ IQueryable provider. If you thought this series would last this long then you must have some eerie metaphysical powers of insight that go beyond mere blind faith in the gods of the interwebs. So powerful, in fact, you may now be considered a threat to national security, since with all your witchery and kanoodling you might be secretly tapping the thoughts and provoking the actions of persons in higher office into doing unthinkable, irrevocable things. You may think you are doing good by protecting the innocent from master villains like Sylar, but the normals will still fear you anyway. You might want to keep a lookout for strange black sedans parked down the street from your home. I know I do. </P>
<P><A href="http://blogs.msdn.com/mattwar/pages/linq-links.aspx" mce_href="http://blogs.msdn.com/mattwar/pages/linq-links.aspx">Complete list of posts in the “Building an IQueryable Provider” series</A></P>
<P>I feel like I’m finally putting the finishing touches on this masterpiece. Sure, there’s always more to do, but the deliberate loose ends that I left in the product so you would have something to fret about are finally being seen to.</P>
<P><STRONG>What's inside:</STRONG></P>
<BLOCKQUOTE>
<P><STRONG>Cleaning House</STRONG>– I’ve thrown down the gauntlet on FieldReader.&nbsp; </P>
<P><STRONG>Automatic Caching</STRONG> – Entity providers get automatic query caching. </P>
<P><STRONG>Automatic Loading</STRONG> – Finally a usable implementation of QueryPolicy. <BR><BR><STRONG>Split Personalities</STRONG> – Language, Mapping and Policy each split into two classes. <BR><BR><STRONG>Provider Abstraction</STRONG> – Build entity providers that use API’s other than ADO. </P></BLOCKQUOTE>
<P><STRONG>The full source code and redistributable DLL's can be found at: </STRONG></P>
<P><A href="http://www.codeplex.com/IQToolkit" mce_href="http://www.codeplex.com/IQToolkit">http://www.codeplex.com/IQToolkit</A></P>
<H5><BR>Fielding a new Reader</H5>
<P>I was not too happy with the state of the FieldReader class in the last installment. It was a bit quirky that it relied on exception handling to function whenever the entity member type did not match the database’s column type, at least in how the database provider chose to represent it.&nbsp; I normally pride myself on sticking to my guns, and I’ve always told myself to never, ever, use exception handling for anything except for handling truly exceptional cases, and a mismatch like this was not really an exceptional case, since it happens quite a lot when the whole purpose of having a mapping system is to allow for just this sort of flexibility between the representation of objects in the programming language and that of the tables in the database.&nbsp; And besides, it wasn’t fast enough.</P>
<P>What I was really trying to do was enable the object materialization code that is built by the ExecutionBuilder class to operate as fast as it could, without relying on a bunch of runtime checks and coercions to get the data into the right form.&nbsp; I wanted to be able to determine at query build time the correct method to call on the DataReader without having to verify each time a field is read that its going to work (because most of the ADO providers just give up and throw exceptions when you ask for the data in the wrong form). I introduced the FieldReader class as a way to isolate the logic that would attempt to reduce this overhead (so I didn’t have to force all this logic in to pure expression node format).&nbsp; Yet, the FieldReader itself still had the problem of trying to figure out if the call it was about to make against the DataReader was going to succeed or not.&nbsp; So to avoid the call to GetFieldType() each time, I bailed out and just wrapped the whole thing in a try-catch, falling back to the expensive GetValue call on the DataReader whenever the provider balked at my tenacity.</P>
<P>Looking at the problem again, I realized that it wasn’t the call to GetFieldType() that was so expensive, it was calling it every time I read the field.&nbsp; If I could simply call it once per query per field, then I could know the right course of action for each row without the cost, and without the exceptions.&nbsp; What I needed to be able to do was to save state about the specific query execution, per data reader, per field. But alas, the FieldReader class was just a bunch of static methods. </P>
<P>I needed to build a better mouse trap.</P>
<P>Getting state to be stored per query is not too difficult, since I create a new instance of a materializer for each query, so there is at least something to stick data onto, even if it might be awkward to do it.&nbsp; Yet, getting state per DataReader is much more difficult since there may be multiple DataReaders in a single query (think hierarchical results with preloaded associations.)&nbsp; What I needed was an abstraction for reading fields that would be different and adjustable for each DataReader. Of course, that’s the point where the aha for the aha moment occurred, and I realized that what I really needed was to abstract the DataReader out of the problem.&nbsp; </P>
<P>Introducing the new FieldReader.&nbsp; Its now a DataReader, or at least it looks like one.&nbsp; It’s the equivalent of a DataReader but defined by the entity provider, not the ADO provider.&nbsp; It wraps a DataReader and holds onto whatever state it pleases.</P>
<P>So let’s take a look at how it gets to be fast.</P>
<P>The FieldReader is an abstract base, and it doesn’t know a thing about DataReader’s at all.&nbsp; It exposes ReadXXXX methods to the materializer, and abstracts over a DataReader by declaring abstract methods that correspond to DataReader methods.</P><PRE class=code><SPAN style="COLOR: blue">public abstract class </SPAN><SPAN style="COLOR: #2b91af">FieldReader
</SPAN>{
    <SPAN style="COLOR: #2b91af">TypeCode</SPAN>[] typeCodes;

    <SPAN style="COLOR: blue">public </SPAN>FieldReader()
    {
    }

    <SPAN style="COLOR: blue">protected void </SPAN>Init()
    {
        <SPAN style="COLOR: blue">this</SPAN>.typeCodes = <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">TypeCode</SPAN>[<SPAN style="COLOR: blue">this</SPAN>.FieldCount];
    }

    <SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">Byte </SPAN>ReadByte(<SPAN style="COLOR: blue">int </SPAN>ordinal)
    {
        <SPAN style="COLOR: blue">if </SPAN>(<SPAN style="COLOR: blue">this</SPAN>.IsDBNull(ordinal))
        {
            <SPAN style="COLOR: blue">return default</SPAN>(<SPAN style="COLOR: #2b91af">Byte</SPAN>);
        }
        <SPAN style="COLOR: blue">while </SPAN>(<SPAN style="COLOR: blue">true</SPAN>)
        {
            <SPAN style="COLOR: blue">switch </SPAN>(typeCodes[ordinal])
            {
                <SPAN style="COLOR: blue">case </SPAN><SPAN style="COLOR: #2b91af">TypeCode</SPAN>.Empty:
                    typeCodes[ordinal] = GetTypeCode(ordinal);
                    <SPAN style="COLOR: blue">continue</SPAN>;
                <SPAN style="COLOR: blue">case </SPAN><SPAN style="COLOR: #2b91af">TypeCode</SPAN>.Byte:
                    <SPAN style="COLOR: blue">return this</SPAN>.GetByte(ordinal);
                <SPAN style="COLOR: blue">case </SPAN><SPAN style="COLOR: #2b91af">TypeCode</SPAN>.Int16:
                    <SPAN style="COLOR: blue">return </SPAN>(<SPAN style="COLOR: #2b91af">Byte</SPAN>)<SPAN style="COLOR: blue">this</SPAN>.GetInt16(ordinal);
                <SPAN style="COLOR: blue">case </SPAN><SPAN style="COLOR: #2b91af">TypeCode</SPAN>.Int32:
                    <SPAN style="COLOR: blue">return </SPAN>(<SPAN style="COLOR: #2b91af">Byte</SPAN>)<SPAN style="COLOR: blue">this</SPAN>.GetInt32(ordinal);
                <SPAN style="COLOR: blue">case </SPAN><SPAN style="COLOR: #2b91af">TypeCode</SPAN>.Int64:
                    <SPAN style="COLOR: blue">return </SPAN>(<SPAN style="COLOR: #2b91af">Byte</SPAN>)<SPAN style="COLOR: blue">this</SPAN>.GetInt64(ordinal);
                <SPAN style="COLOR: blue">case </SPAN><SPAN style="COLOR: #2b91af">TypeCode</SPAN>.Double:
                    <SPAN style="COLOR: blue">return </SPAN>(<SPAN style="COLOR: #2b91af">Byte</SPAN>)<SPAN style="COLOR: blue">this</SPAN>.GetDouble(ordinal);
                <SPAN style="COLOR: blue">case </SPAN><SPAN style="COLOR: #2b91af">TypeCode</SPAN>.Single:
                    <SPAN style="COLOR: blue">return </SPAN>(<SPAN style="COLOR: #2b91af">Byte</SPAN>)<SPAN style="COLOR: blue">this</SPAN>.GetSingle(ordinal);
                <SPAN style="COLOR: blue">case </SPAN><SPAN style="COLOR: #2b91af">TypeCode</SPAN>.Decimal:
                    <SPAN style="COLOR: blue">return </SPAN>(<SPAN style="COLOR: #2b91af">Byte</SPAN>)<SPAN style="COLOR: blue">this</SPAN>.GetDecimal(ordinal);
                <SPAN style="COLOR: blue">default</SPAN>:
                    <SPAN style="COLOR: blue">return this</SPAN>.GetValue&lt;<SPAN style="COLOR: #2b91af">Byte</SPAN>&gt;(ordinal);
            }
        }
    }<BR></PRE><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A>
<P>The ReadByte method shows an example of how this works.&nbsp; The FieldReader holds onto an array of TypeCodes, one per field, and uses it to determine which underlying method to call on the DataReader.&nbsp; It doesn’t actually call the DataReader directly, since the FieldReader class does not actually know about a DataReader, but it does have abstract methods that a provider can implement to communicate to its model of reading data.&nbsp; The first time this method is called for a particular field ordinal, the TypeCode has a value of Empty.&nbsp; If this is the case it simply computes the correct TypeCode and tries again.&nbsp; A switch statement directs the code to the correct data reading method.</P>
<P>Now that I’ve done it, it seems almost obvious.&nbsp; Getting the rest of the stack to talk about FieldReaders instead of DataReaders took some work, and lead to more fiddling and changes, but I’ll get to that later.</P>
<P><STRONG>Automatic Caching</STRONG></P>
<P>In the last version I introduce the QueryCache object and showed how you could use it to get many of the benefits of a pre-compiled query without actually pre-compiling it.&nbsp; Yet, still, in order to use it you had to use it directly each time you wanted to execute a query. That was a bit awkward, but I was hesitant about going further at the time, worried that an automatic caching feature may have undesired effects for particular kinds of queries.&nbsp; I speculated that it was not possible to determine precisely which sub expressions in a query ought to be handled as database parameters and which could be safely identified as constants (some queries cannot work with parameters in particular spots). However, an IQToolkit user called me out on this and showed me the light.&nbsp; I was humbled.</P>
<P>Now you are receiving the benefit in a new feature.&nbsp; The automatic query cache.&nbsp; </P>
<P>Each EntityProvider (the new name for the provider base class, and yes it does change every version) now has a Cache property that can be assigned an instance of a QueryCache.&nbsp; If the entity provider is given a cache it will automatically use that cache when executing queries. So now you can simply execute queries like normal, without pre-compiling, and if you execute what looks to be the same query again, it executes faster the second time.</P>
<P>How much faster is it really? <BR><BR>Unfortunately, it is still not as fast as having pre-compiled queries. Not by a long shot. The cost of actually looking in the cache and finding an equivalent already compiled query is still rather expensive.&nbsp; </P>
<P>What is the expensive part?</P>
<P>The most expensive part of this re-use is not comparing expression trees, but isolating the parameter values. I have to break the query down into two parts, the common query base and the parameters specified in the new query. I then match the new query’s common base with the prior executed queries to find a previously compiled query to reuse, but in order to execute the previous query I need to supply the new parameter values and in order to do that I have to turn expression tree fragments into values. </P>
<P>I can evaluate LINQ expressions by turning each one into a zero-parameter lambda and using LINQ’s own feature of compiling lambdas into delegates that can then be invoked to get values. Yet that feature, like pre-compiled queries, works great if I am going to evaluate the same expression over and over again.&nbsp; It’s a huge amount of overhead if I just want to evaluate the expression once. </P>
<P>The worse part of it all is realizing that was exactly what the partial evaluator was doing.&nbsp; It was isolating sub expressions and evaluating them using the LINQ compile feature, and yet these compiled delegates were only ever being invoked once.</P>
<P>I seriously needed a way to evaluate LINQ expressions without using Reflection.Emit.&nbsp; This is probably the point where YOU think “aha”, and predict I’m just being sneaky by leading up to discussing that very same expression evaluator that I included as source code in the last version.&nbsp; But I’m not.&nbsp; I’m not sneaky or even leading up to it.&nbsp; Because that evaluator wasn’t any faster.</P>
<P>What’s a developer left to do?&nbsp; </P>
<P>Handle the common cases as simply and straight-forward as possible and leave the ugly stuff to LINQ.&nbsp; So, I’ve added a bit of *quick* direct reflection calls to the partial evaluator that gets used in the common cases of basic field accesses, which happens a lot in C# when you write queries that reference locals that get captured in state classes.&nbsp; </P>
<P>It is really bizarre to discover that reflection API is the faster solution, after spending so much effort trying to work around it.</P>
<P><STRONG>Automatic Loading</STRONG></P>
<P>The only piece missing so far in making the toolkit a ready-to-use library for building apps on top of was its lack in any meaningful way of controlling deferred loading of associations.&nbsp; I designed in the QueryPolicy abstraction as a way to guide the query translator and executor in doing the right thing, but the only way of actually setting up a policy was to invent your own implementation of one.&nbsp; I figure about three of you actually did that.&nbsp; The rest sent me mail saying that deferred loading did not work.</P>
<P>Fortunately, I’m here to tell you that has all changed. There’s a new class in town and its ready to be instantiated.</P>
<P>I give you the EntityPolicy.</P>
<P>It works similarly to LINQ to SQL’s DataLoadOptions. You construct an instance of one and then call some methods on it telling it how you would like each association to be loaded or not and whether to either defer its loading or load it up front.</P><PRE class=code><SPAN style="COLOR: blue">var </SPAN>db = <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">Northwind</SPAN>(provider);

<SPAN style="COLOR: blue">var </SPAN>policy = <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">EntityPolicy</SPAN>();
policy.IncludeWith&lt;<SPAN style="COLOR: #2b91af">Customer</SPAN>&gt;(c =&gt; c.Orders);
provider.Policy = policy;

<SPAN style="COLOR: blue">var </SPAN>cust = db.Customers.Single(c =&gt; c.CustomerID == <SPAN style="COLOR: #a31515">"ALFKI"</SPAN>);</PRE><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A>
<P>Use the IncludeWith() method to instruct the provider to include the Orders property when the Customer type is retrieved.&nbsp; This will result in an query returns back all the data for customers and their related orders.&nbsp; </P>
<P>The query looks like this when run against the Access test database:</P>
<P><FONT color=#008000 face="Courier New">PARAMETERS p0 NVarChar; <BR>SELECT t1.[CustomerID], t1.[OrderDate], t1.[OrderID] <BR>FROM [Customers] AS t0 <BR>LEFT OUTER JOIN [Orders] AS t1 <BR>&nbsp; ON (t1.[CustomerID] = t0.[CustomerID]) <BR>WHERE (t0.[CustomerID] = p0) <BR>-- p0 = [ALFKI] </FONT></P>
<P><FONT color=#008000 face="Courier New">PARAMETERS p0 NVarChar; <BR>SELECT t0.[City], t0.[CompanyName], t0.[ContactName], t0.[Country], t0.[CustomerID], t0.[Phone] <BR>FROM [Customers] AS t0 <BR>WHERE (t0.[CustomerID] = p0) <BR>-- p0 = [ALFKI]</FONT></P>
<P><BR>It is actually two queries; one for customers and one for orders.</P>
<P>If you want to retrieve order details too you’ll need to modify your policy like this:</P><PRE class=code><SPAN style="COLOR: blue">var </SPAN>db = <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">Northwind</SPAN>(provider);

<SPAN style="COLOR: blue">var </SPAN>policy = <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">EntityPolicy</SPAN>();
policy.IncludeWith&lt;<SPAN style="COLOR: #2b91af">Customer</SPAN>&gt;(c =&gt; c.Orders);
policy.IncludeWith&lt;<SPAN style="COLOR: #2b91af">Order</SPAN>&gt;(o =&gt; o.Details);
provider.Policy = policy;

<SPAN style="COLOR: blue">var </SPAN>cust = db.Customers.Single(c =&gt; c.CustomerID == <SPAN style="COLOR: #a31515">"ALFKI"</SPAN>);</PRE>
<P>And the query will turn into three separate queries; one each for customers, orders and order-details:</P>
<P><FONT color=#008000 face="Courier New">PARAMETERS p0 NVarChar; <BR>SELECT t2.[OrderID], t2.[ProductID] <BR>FROM ([Customers] AS t0 <BR>LEFT OUTER JOIN [Orders] AS t1 <BR>&nbsp; ON (t1.[CustomerID] = t0.[CustomerID])) <BR>LEFT OUTER JOIN [Order Details] AS t2 <BR>&nbsp; ON (t2.[OrderID] = t1.[OrderID]) <BR>WHERE (t0.[CustomerID] = p0) <BR>-- p0 = [ALFKI] </FONT></P>
<P><FONT color=#008000 face="Courier New">PARAMETERS p0 NVarChar; <BR>SELECT t1.[CustomerID], t1.[OrderDate], t1.[OrderID] <BR>FROM [Customers] AS t0 <BR>LEFT OUTER JOIN [Orders] AS t1 <BR>&nbsp; ON (t1.[CustomerID] = t0.[CustomerID]) <BR>WHERE (t0.[CustomerID] = p0) <BR>-- p0 = [ALFKI] </FONT></P>
<P><FONT color=#008000 face="Courier New">PARAMETERS p0 NVarChar; <BR>SELECT t0.[City], t0.[CompanyName], t0.[ContactName], t0.[Country], t0.[CustomerID], t0.[Phone] <BR>FROM [Customers] AS t0 <BR>WHERE (t0.[CustomerID] = p0) <BR>-- p0 = [ALFKI]</FONT></P>
<P>If you want to include Orders with Customers, but not up front, you can specify an option on the IncludeWith method to defer loading of this property.&nbsp; This will only work if the association property has been declared as a DeferredList&lt;Order&gt; or equivalent type (like a simple IList&lt;Order&gt; that can be assigned a DeferredList.)&nbsp; Otherwise, you’ll simply force the deferred query to be executed immediately upon assignment, which will be much less efficient than simply instructing the policy to include them without deferring.</P><PRE class=code><SPAN style="COLOR: blue">var </SPAN>db = <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">Northwind</SPAN>(provider);

<SPAN style="COLOR: blue">var </SPAN>policy = <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">EntityPolicy</SPAN>();
policy.IncludeWith&lt;<SPAN style="COLOR: #2b91af">Customer</SPAN>&gt;(c =&gt; c.Orders, <SPAN style="COLOR: blue">true</SPAN>);
provider.Policy = policy;

<SPAN style="COLOR: blue">var </SPAN>cust = db.Customers.Single(c =&gt; c.CustomerID == <SPAN style="COLOR: #a31515">"ALFKI"</SPAN>);</PRE><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A>
<P>Now, when you execute the query you only see the first query for customers until you actually look inside the Orders collection.</P>
<P><STRONG>Automatic Filtering and Ordering Associations</STRONG></P>
<P>Filtering or ordering an association collection can be done when you include it using the IncludeWith method or separately by using the AssociateWith method.</P><PRE class=code><SPAN style="COLOR: blue">var </SPAN>db = <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">Northwind</SPAN>(provider);

<SPAN style="COLOR: blue">var </SPAN>policy = <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">EntityPolicy</SPAN>();
policy.IncludeWith&lt;<SPAN style="COLOR: #2b91af">Customer</SPAN>&gt;(c =&gt; <SPAN style="COLOR: blue">from </SPAN>o <SPAN style="COLOR: blue">in </SPAN>c.Orders <SPAN style="COLOR: blue">where </SPAN>o.OrderDate.Month == 1 <SPAN style="COLOR: blue">select </SPAN>o);
provider.Policy = policy;

<SPAN style="COLOR: blue">var </SPAN>cust = db.Customers.Single(c =&gt; c.CustomerID == <SPAN style="COLOR: #a31515">"ALFKI"</SPAN>);</PRE>
<P>This is logically the same as using IncludeWith and AssociateWith separately:</P><PRE class=code><SPAN style="COLOR: blue">var </SPAN>db = <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">Northwind</SPAN>(provider);

<SPAN style="COLOR: blue">var </SPAN>policy = <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">EntityPolicy</SPAN>();
policy.IncludeWith&lt;<SPAN style="COLOR: #2b91af">Customer</SPAN>&gt;(c =&gt; c.Orders);
policy.AssociateWith&lt;<SPAN style="COLOR: #2b91af">Customer</SPAN>&gt;(c =&gt; <SPAN style="COLOR: blue">from </SPAN>o <SPAN style="COLOR: blue">in </SPAN>c.Orders <SPAN style="COLOR: blue">where </SPAN>o.OrderDate.Month == 1 <SPAN style="COLOR: blue">select </SPAN>o);
provider.Policy = policy;

<SPAN style="COLOR: blue">var </SPAN>cust = db.Customers.Single(c =&gt; c.CustomerID == <SPAN style="COLOR: #a31515">"ALFKI"</SPAN>);</PRE>
<P>Both produce the same queries:</P>
<P><FONT color=#008000 face="Courier New">PARAMETERS p0 NVarChar; <BR>SELECT t1.[CustomerID], t1.[OrderDate], t1.[OrderID] <BR>FROM [Customers] AS t0 <BR>LEFT OUTER JOIN [Orders] AS t1 <BR>&nbsp; ON ((t1.[CustomerID] = t0.[CustomerID]) AND (Month(t1.[OrderDate]) = 1)) <BR>WHERE (t0.[CustomerID] = p0) <BR>-- p0 = [ALFKI] </FONT></P>
<P><FONT color=#008000 face="Courier New">PARAMETERS p0 NVarChar; <BR>SELECT t0.[City], t0.[CompanyName], t0.[ContactName], t0.[Country], t0.[CustomerID], t0.[Phone] <BR>FROM [Customers] AS t0 <BR>WHERE (t0.[CustomerID] = p0) <BR>-- p0 = [ALFKI]</FONT></P>
<P>It is also perfectly legal to specify the AssociateWith before the IncludeWith, or even without one.&nbsp; An AssociateWith by itself will still cause filtering to occur when the association property is used as part of the query. <BR></P>
<P><STRONG>Automatic Filtering Entities</STRONG></P>
<P>It is also possible to specify filter operations that apply to entities anytime they are referenced, not just via an association.&nbsp; You can use the Apply() method to apply any query operation over an entity table any time it is referenced in the query.</P>
<P>For example, image you wanted to limit the customer list to only customers in a particular city, and any query over customers would automatically get this restriction.</P><PRE class=code><SPAN style="COLOR: blue">var </SPAN>db = <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">Northwind</SPAN>(provider);

<SPAN style="COLOR: blue">var </SPAN>policy = <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">EntityPolicy</SPAN>();
policy.Apply&lt;<SPAN style="COLOR: #2b91af">Customer</SPAN>&gt;(custs =&gt; <SPAN style="COLOR: blue">from </SPAN>c <SPAN style="COLOR: blue">in </SPAN>custs <SPAN style="COLOR: blue">where </SPAN>c.City == <SPAN style="COLOR: #a31515">"London" </SPAN><SPAN style="COLOR: blue">select </SPAN>c);
provider.Policy = policy;

<SPAN style="COLOR: blue">var </SPAN>custCount = db.Customers.Count();</PRE><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A>
<P>So even when the Count() aggregate is used, the query includes this filter.</P>
<P><FONT color=#008000 face="Courier New">PARAMETERS p0 NVarChar; <BR>SELECT COUNT(*) <BR>FROM [Customers] AS t0 <BR>WHERE (t0.[City] = p0) <BR>-- p0 = [London]</FONT></P>
<P>Of course, you can use this feature for more than just filtering, as long as the query returns the same types of objects that originated in the original table.</P>
<P><STRONG>Split Personalities</STRONG> </P>
<P>If you dig a little beneath the surface of the new sources, or if you really are building your own providers based on the toolkit, you’ll notice a big change that has occurred with the definition of the language, mapping and policy objects.&nbsp; Each of them has been split into two.&nbsp; The intention is to separate the models from the behaviors.&nbsp; In their prior incarnations, each of these classes both specified an API that exposed information about each area and at the same time had methods that directly took responsibility over a stage of query translation.&nbsp; </P>
<P>So with a QueryLanguage you get a QueryLinguist that applies language specific transformations to queries; with QueryMapping you get a QueryMapper that applies the mapping and with QueryPolicy you get the QueryPolice, that enforces the rules about associations and inclusion.&nbsp; (And as a benefit you can with a straight face, tell users that yes there&nbsp;are query police and they’ll come get if you continue to writer queries like that.)</P>
<P>Separating these out had the side effect of solving some awkward problems in the design.&nbsp; For example, the necessity to have a fully specified QueryLanguage in existence before a QueryMapping can be created, since the translation steps of the mapper sometimes depend on the model of the language, yet a correct QueryLanguage model must be chosen&nbsp; by the provider, which in turn depends on the mapping.&nbsp; So there was an almost cyclic dependency that required the user to know more than would otherwise be necessary about the provider before constructing one.</P>
<P>Separating out the behaviors allow each language, mapping and policy to be specified separate of one another, enabling the provider to choose the language directly.</P>
<P><STRONG>Provider Abstraction</STRONG> </P>
<P>It always bothered me that the backend models for these IQToolkit providers where directly tied to System.Data.&nbsp; It made a sort of sense, because most existing data access API’s on .Net are System.Data providers, so this dependency works for most uses.&nbsp; However, there is so much other code in the toolkit that could be applied to build query providers on top of other API’s that it was unfortunately that the ADO types, connection, transaction, etc, were tied in at such a low level. </P>
<P>So keeping in the spirit of always changing everything, I’ve once again refactored the base classes for entity providers.&nbsp; </P>
<P>So EntityProvider is the new abstract base class for providers that brings in the model of query translations, languages, mapping and policies, but does not depend on ADO.&nbsp; DbEntityProvider then derives from this and introduces connections and transactions.&nbsp; The existing query providers for TSQL, Access, SQL compact, MySql and SqlLite are all based off the&nbsp; DbEntityProvider class. Yet, it is now possible to build a provider that is based on another API and yet still make use of the rest of the infrastructure.</P>
<P>EntitySession is the class to use for sessions.&nbsp; It is not an abstract base, but it no longer depends on ADO types and functions entirely in conjunction with an EntityProvider.&nbsp; So it’s possible to use sessions with new style providers.</P>
<P>Even QueryTypeSystem has been simplified to not reference System.Data types, and a new DbTypeSystem class has been introduced to add knowledge of data types like DbType and SqlType.</P>]]></content:encoded>
    </item>
    <item>
      <title>Building a LINQ IQueryable Provider – Part XVI (IQToolkit 0.16)</title>
      <link>https://docs.microsoft.com/archive/blogs/mattwar/building-a-linq-iqueryable-provider-part-xvi-iqtoolkit-0-16</link>
      <pubDate>Tue, 15 Sep 2009 17:50:00 GMT</pubDate>
      <dc:creator><![CDATA[Matt Warren - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mattwar/2009/09/15/building-a-linq-iqueryable-provider-part-xvi-iqtoolkit-0-16/</guid>
      <description><![CDATA[This is the sixteenth in a series of posts on how to build a LINQ IQueryable provider. If you have...]]></description>
      <content:encoded><![CDATA[<P>This is the <EM>sixteenth </EM>in a series of posts on how to build a LINQ IQueryable provider. If you have not read the previous posts you might try rolling into a ball and crying for momma. That’s right, reading on is as hazardous to your health as a skinned knee. Just be warned and have an anti-biotic on hand. </P>
<P><A href="http://blogs.msdn.com/mattwar/pages/linq-links.aspx" mce_href="http://blogs.msdn.com/mattwar/pages/linq-links.aspx">Complete list of posts in the Building an IQueryable Provider series</A></P>
<P>I would have had the update out sooner but I couldn’t think of what to write in this excuse slot. My excuse generator was down for scheduled maintenance but did not come back on line as planned and wouldn’t you know it the techie responsible gave me all sorts of lame excuses. Some people! <BR></P>
<P><STRONG>What's inside:</STRONG></P>
<BLOCKQUOTE>
<P><STRONG>Performance</STRONG> – I’ve actually tried to improve things.</P>
<P><STRONG>Caching</STRONG> – Re-use queries without the burden of defining delegates.</P>
<P><STRONG>Evaluation</STRONG> – Execute expression trees without Reflection.Emit.</P>
<P><STRONG>Bug Fixes</STRONG> – Most of the bugs reported on CodePlex are fixed.</P></BLOCKQUOTE>
<P><STRONG><BR>The full source code and redistributable DLL's can be found at: </STRONG></P>
<P><A href="http://www.codeplex.com/IQToolkit" mce_href="http://www.codeplex.com/IQToolkit">http://www.codeplex.com/IQToolkit</A></P>
<H3>Faster is Better</H3>
<P>One of the big things I tried to tackle this time around was to finally do some performance improvements.&nbsp; Until now, the only performance considerations were in the design of compiled queries and the use of compiled LINQ expressions for materializing objects.&nbsp; Yet, when I looked at actual performance of compiled queries versus straight ADO, there was still a lot of overhead.</P>
<P>Where was the time being spent?&nbsp; As it turns out, even though I was compiling a LINQ expression to represent the execution plan and an explicit function to convert DataReader rows into objects, ideally making the writing of data into objects as fast as possible, there was still room for improvement. The problem was not the writing of data into objects, but reading the data from the DataReader. I wholely blame myself for this. In an attempt to simplify the IQToolkit source code way back in one of the original posts I chose to read data using the general DataReader.GetValue method. This has two undesirable side effects; 1) the value is returned typed as object, which mean all non reference types (mostly numeric and datetime types) are boxed, which is measurably significant, and 2) in order to make sure the value was in the correct form to write it into the object I now had to coerce it back (which immediately led to an unbox operation, equally as significant.) </P>
<P>I tried many variations of solutions. Ideally, the runtime code would simply know which field access method of the DataReader to call and to coerce the results only if necessary. Unfortunately, the translation engine does not track enough information to be 100% certain of the data type the provider will return. It can make a good guess, but if it is wrong then the query will die in a fiery exception that halts the program and sends your manager storming toward your office. The solution I chose was sort of a hybrid.&nbsp; Based on an expected value type a type specific helper method is now invoked. This method calls the equivalent DataReader method inside of a try-catch. I know, I hate having to use try-catch in this way, but the cheap cost of setting up the try-catch and the rare condition where the guess is wrong led me to the dark side. I will now change the color of my light-saber from blue to red. <BR><BR>Here’s an example of the GetInt32 helper method.</P><PRE class=code><SPAN style="COLOR: blue">public static class </SPAN><SPAN style="COLOR: #2b91af">FieldReader
</SPAN>{<BR>  ...<BR>  <SPAN style="COLOR: blue">public static </SPAN><SPAN style="COLOR: #2b91af">Int32 </SPAN>GetInt32(<SPAN style="COLOR: #2b91af">DbEntityProviderBase </SPAN>provider, <SPAN style="COLOR: #2b91af">DbDataReader </SPAN>reader, <SPAN style="COLOR: blue">int </SPAN>ordinal)
  {
     <SPAN style="COLOR: blue">if </SPAN>(reader.IsDBNull(ordinal))
     {
         <SPAN style="COLOR: blue">return default</SPAN>(<SPAN style="COLOR: #2b91af">Int32</SPAN>);
     }
     <SPAN style="COLOR: blue">try
     </SPAN>{
         <SPAN style="COLOR: blue">return </SPAN>reader.GetInt32(ordinal);
     }
     <SPAN style="COLOR: blue">catch
     </SPAN>{
         <SPAN style="COLOR: blue">return </SPAN>(<SPAN style="COLOR: #2b91af">Int32</SPAN>)provider.Convert(reader.GetValue(ordinal), <SPAN style="COLOR: blue">typeof</SPAN>(<SPAN style="COLOR: #2b91af">Int32</SPAN>));
     }
  }
  ...
}</PRE>
<P>As long as the expected type is correct, the faster DataReader.GetInt32 method is called. If that fails, then the fallback is to call the general GetValue method and coerce the result.&nbsp; This should rarely happen.</P>
<P>This is all it took to get the compiled query into very low overhead versus direct ADO calls; mostly less than 3%. I’ve added a performance test you can run to check it out on your set up. Of course, this will vary depending on the query, the hardware, the load on the server and the network latency.</P>
<H3>Caching Queries</H3>
<P>“Why can’t the provider simply cache the queries for me.”&nbsp; I’ve gotten this request a lot.&nbsp; Sometimes from direct pleas in email, other times from those of you trying to do it yourself and asking for advice.&nbsp; </P>
<P>It seems natural to imagine that it would only take a little bit of work for a provider to determine if a query being executed now is the same or similar to one executed before, so why is the only way to re-use a query to specify one using the cryptic syntax of generic methods, lambda expressions and delegates?&nbsp; And why do I have to hold onto the thing myself, can’t some service do this for me?</P>
<P>Of course, my usual reaction is to give a heavy sigh in the privacy of my office and then craft a quite sensible fire-and-brimstone reply, complete with infallible logic and dramatic consternation, as to why and how you really are better off with the compiled query solution. But I’m tired of doing that, so instead of impressing you with my sound reasoning I’m going to show you how I went ahead and just did it. I like challenges, and there’s no better challenge than the impossible, or the sometimes impractical, or the generally ill-advised. </P>
<P>What I built is a new piece of code called the ‘QueryCache’.&nbsp; It is actually implemented to be generic enough that it will work with your own IQueryable provider. Yet its not currently integrated into any provider, though you may choose to embed it into yours.&nbsp; You can, however, use the cache as is to execute your queries and take advantage of its cache-y goodness. You don’t have to make delegates and invoke them, you simply have to give the cache your query and it will give you back the results.</P>
<BLOCKQUOTE><PRE class=code><SPAN style="COLOR: blue">var </SPAN>cache = <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">QueryCache</SPAN>(10);
<SPAN style="COLOR: blue">var </SPAN>query = <SPAN style="COLOR: blue">from </SPAN>c <SPAN style="COLOR: blue">in </SPAN>db.Customers <SPAN style="COLOR: blue">where </SPAN>c.City == <SPAN style="COLOR: #a31515">"London" </SPAN><SPAN style="COLOR: blue">select </SPAN>c;
<SPAN style="COLOR: blue">var </SPAN>result = cache.Execute(query);</PRE></BLOCKQUOTE>
<P>Here’s how it works.&nbsp; The cache maintains a most-recently-used list of compiled queries.&nbsp; Every time you execute a query via the cache, the cache compares your query against the ones in the cache. If it finds a match, it simply uses the existing compiled query and invokes it. If not, it makes a new compiled query and adds it to the list. </P>
<P>Of course, that’s the easy part.&nbsp; </P>
<P>The hard part is figuring out how to compare an IQueryable query object against a list of compiled-query delegate objects and determine which ones can be reused. For example, are these two the same query?</P>
<BLOCKQUOTE><PRE class=code><SPAN style="COLOR: blue">var </SPAN>query1 = <SPAN style="COLOR: blue">from </SPAN>c <SPAN style="COLOR: blue">in </SPAN>db.Customers <SPAN style="COLOR: blue">where </SPAN>c.City == <SPAN style="COLOR: #a31515">"London" </SPAN><SPAN style="COLOR: blue">select </SPAN>c;<BR><SPAN style="COLOR: blue">var </SPAN>query2 = <SPAN style="COLOR: blue">from </SPAN>c <SPAN style="COLOR: blue">in </SPAN>db.Customers <SPAN style="COLOR: blue">where </SPAN>c.City == <SPAN style="COLOR: #a31515">"Seattle" </SPAN><SPAN style="COLOR: blue">select </SPAN>c;</PRE></BLOCKQUOTE>
<P>Technically they are different expression trees, but if that’s the deciding factor then I might as well give up now. They are structurally similar and so it is logical to assume that a query compiled for one should be nearly identical to a query compiled for the other. If I were using compiled queries directly I would simply choose to make the name of the city a parameter to the compiled query delegate and invoke it with different values. So isn’t that just what I want the cache to do for me?&nbsp; </P>
<P>To do this I need a little tool that will take a look at a query tree and decide which bits should be considered parameters and then give me back a new query tree with the parameters in place of those bits. As it turns out this is not really all that hard since it seems obvious for the most generality that anything that appears in the query tree as a constant should be deemed a parameter. A trivial expression visitor can produce this.</P>
<P>If it also wraps the rewritten query tree in a lambda expression and gives me back the set of constants that it extracted then I have everything I need to make a compiled query and invoke it with an array of values. I also have what I need to find an already compiled query in the cache, since compiled queries hold onto their defining query trees. So if my first query in the example above is already in the cache, it already has a parameterized query tree defining it and that ought to look awfully similar to the parameterized version of the second query.</P>
<P>The only thing I need now is a way to compare two lambda expressions to see if they are similar.&nbsp; Fortunately, I wrote that ages ago.&nbsp; The ExpressionComparer does just this.&nbsp; </P>
<P>If I cobble all these parts together into a reasonable order I get my QueryCache. Now, I can use compiled queries without ever having to manually define them again!&nbsp; Huzzah!</P>
<P>Yet, if this is so grand, why haven’t I taken that one last step and simply plugged into the base DbEntityProvider class?</P>
<P>Unfortunately, reality is not as rosy and I would hope.</P>
<P>There are a few problems holding me back.&nbsp; The most significant is the silly act of parameterizing itself. The problem with the cache is that it doesn’t know which constants in the query should be made into parameters, so it turns them all into parameters. Yet, as much as I’d like it to be otherwise, databases don’t treat all parameters equally. Sometimes a parameter is terrific for performance; a database like SQL Server optimizes by storing parameterized query plans so you basically get the same benefit client and server.&nbsp; Yet, sometimes, for some bits of SQL, for some back ends, parameters either cannot be used or have crippling effects on speed. So it's usually the best policy to be explicit and judicious when using parameters, something the cache in all its glory cannot chose for you.</P>
<P>So I leave the cache, for now, as something you can explicitly opt-in to using, per query.</P>
<P>Please, give it a try.&nbsp; Feedback is welcome.</P>
<H3>Expression Evaluator</H3>
<P>Sometimes you may want to execute expression trees as code without actually turning it into true runtime code. You may be running on a platform that does not currently support the Expression.Compile() method (or the ability to use Reflection.Emit to generate IL at runtime) like Windows Mobile. I’ve been encouraged by folks here at Microsoft to think about this from time to time, so I set out to explore this space and the result is a whole mess code called the ExpressionEvaluator, which is an expression tree interpreter. I added my experimental solution to the toolkit in case it is beneficial for someone. It is a lot of code, so it doesn’t compile into the library by default. You have to enable it with a specific #define, NOREFEMIT.&nbsp; This will also switch over all direct uses of Reflection.Emit in the toolkit to using this evaluator.</P>
<P>It has a hefty performance overhead, so I would not consider it a viable alternative to Reflection.Emit. I’ve even added many tricks to avoid calls to reflection and boxing. This has made it a lot faster than a naive solution, but still it pales in comparison to real IL.&nbsp; However, in cases where there is no alternative, its probably the best you are going to get.</P>
<H3>Crazy Antics</H3>
<P>In keeping with the spirit of making changes for no good reason, I’ve unbundled the base set of toolkit code from the ADO provider specific bits. So now if you are using IQToolkit to build your own non-ADO based provider you don’t have to be dragging the rest of it along for the ride.&nbsp; All the SQL translation and DbEntityProvider goodness is now in its own DLL, IQToolkit.Data.dll. This means you’ll probably have to tweak your projects to include this new DLL, but that’s about all.</P>
<P>The DLL list is now:</P>
<BLOCKQUOTE>
<P>IQToolkit.dll <BR>IQToolkit.Data.dll <BR>IQToolkit.Data.Access.dll <BR>IQToolkit.Data.SqlClient.dll <BR>IQToolkit.Data.SqlServerCe.dll <BR>IQToolkit.Data.MySql.dll <BR>IQToolkit.Data.SQLite.dll</P></BLOCKQUOTE>
<P>Of course, as always, you only need around the ones you are using, or none of them if you are simply lifting the code out as source.</P>
<H3>That’s All Folks</H3>
<P>I’m sure there are many more wonderful nuggets of goodness I added but forgot to mention.&nbsp; If you discover any of them please file a full report at <A href="http://www.codeplex.com/iqtoolkit" mce_href="http://www.codeplex.com/iqtoolkit">http://www.codeplex.com/iqtoolkit</A>.&nbsp; </P>]]></content:encoded>
    </item>
    <item>
      <title>Building a LINQ IQueryable provider - Part XV (IQToolkit v0.15)</title>
      <link>https://docs.microsoft.com/archive/blogs/mattwar/building-a-linq-iqueryable-provider-part-xv-iqtoolkit-v0-15</link>
      <pubDate>Tue, 16 Jun 2009 20:07:00 GMT</pubDate>
      <dc:creator><![CDATA[Matt Warren - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mattwar/2009/06/16/building-a-linq-iqueryable-provider-part-xv-iqtoolkit-v0-15/</guid>
      <description><![CDATA[This is the fifteenth in a series of posts on how to build a LINQ IQueryable provider. If you have...]]></description>
      <content:encoded><![CDATA[<P>This is the <EM>fifteenth </EM>in a series of posts on how to build a LINQ IQueryable provider. If you have not read the previous posts you might try searching for the audio tapes on <A href="http://www.bing.com/" mce_href="http://www.Bing.com">www.Bing.com</A>.&nbsp; That would be a lot easier than reading. You won't find any, but you'll feel better for having tried. <BR></P>
<P><A href="http://blogs.msdn.com/mattwar/pages/linq-links.aspx" mce_href="http://blogs.msdn.com/mattwar/pages/linq-links.aspx">Complete list of posts in the Building an IQueryable Provider series</A> <BR></P>
<P>Getting this version of the toolkit together has taken a lot of sleepless nights.&nbsp; Thank goodness for Netflix or I'd have had to spend those sleepless nights actually working on the Toolkit.</P>
<P>Okay, enough with the flavor text, let's get to the crunch. <BR></P>
<P><STRONG>What's inside:</STRONG></P>
<BLOCKQUOTE>
<P><STRONG>More Providers</STRONG> - MySQL and SQLite join the previous MS only line up.</P>
<P><STRONG>Transactions</STRONG> - Use ADO transactions to control the isolation of your queries &amp; updates.</P>
<P><STRONG>Entity Providers</STRONG> - The provider concept is expanded to include tables of entities</P>
<P><STRONG>Entity Sessions</STRONG> - The session concept adds identity caching, change tracking and deferred updates via SubmitChanges</P>
<P><STRONG>Provider Factory</STRONG> - Create providers on the fly w/o knowing anything more than the database name and mapping.</P>
<P><STRONG>Madness</STRONG></P></BLOCKQUOTE>
<P><STRONG><BR>The full source code and redistributable DLL's can be found at: </STRONG></P>
<P><A href="http://www.codeplex.com/IQToolkit" mce_href="http://www.codeplex.com/IQToolkit">http://www.codeplex.com/IQToolkit</A></P>
<H3>More Providers</H3>
<UL>
<LI><STRONG>MySQL</STRONG> -- With the stewardship of MySQL in doubt after the purchase of Sun by Oracle, I was leery of taking on the challenge of making a MySQL provider for the toolkit. Yet, the benefits of doing so turned out to be very significant and not just for the MySQL users, as it forced me to challenge some of my very assumptions about SQL which in turn made some of my meager testing better, which in turn made the toolkit better as a whole.&nbsp; <BR><BR>I was surprised when I went to download the free and open-source database product that I had to fill out a bunch of information on myself and wait for a formal approval (that took many days) before I was *allowed* to access the product. This seemed like an awful lot of hassle and odd for an open source project; way too corporate. Fortunately, I persisted and got the server up an running with no problem. Next I searched high and low for MySQL version of Northwind so I could have something to run the tests against. If only Bing were available then!&nbsp; I had to settle for plain ol' Live Search. Fortunately I found what I was looking for, even if it didn't offer me any cash back. <BR><BR>MySQL seems to me what you get if you take a bunch of C programmers and tell them to make a SQL database product and yet offer no guidance. This is not criticism, just a bit of snarky wit over many of the underscore endowed API's that make up the product. Luckily, you'll not need to worry yourself about the manual dexterity needed to type such awkward function names, as you'll be using LINQ and the MySQL provider will do the work for you. On the positive side, the function library of MySQL is quite large and feature rich. I had no problem finding appropriate translations. MySQL even had many interesting features that I'd like to go back and refactor the toolkit to take advantage of.&nbsp; Next release maybe. <BR><BR>There were a few problems I uncovered while trying to get MySQL to pass the test suites.&nbsp; I took the opportunity to fill out the execution suite that has languished for a few releases now, so I could actually assert what the correct output ought to be for specific queries. In almost all the cases MySQL did the right thing (as far as I was expecting.)&nbsp; In most of the cases that it did not appear to do the right thing, it often turned out to be bad assumptions on my part about collation ordering and so removing those assumptions from the tests fixed everything up. The remaining problem still boggles my mind. <BR><BR>In a test designed merely to prove that the translation of simple joins succeeded to generate the right query, the database did not return the correct number of rows.&nbsp; <BR><BR><FONT color=#0000ff>from</FONT> c <FONT color=#0000ff>in</FONT> db.Customers <BR><FONT color=#0000ff>from</FONT> o <FONT color=#0000ff>in</FONT> c.Orders <BR><FONT color=#0000ff>from</FONT> d <FONT color=#0000ff>in</FONT> o.Details <BR><FONT color=#0000ff>select</FONT> d.ProductId <BR><BR>which executes a MySql query that looks like this: <BR><BR><FONT color=#008000>SELECT d.ProductId <BR>FROM [Customers] AS c <BR>LEFT OUTER JOIN [Orders] AS o ON o.CustomerID = c.CustomerID <BR>LEFT OUTER JOIN [Order_Details] AS d ON d.OrderID = o.OrderID <BR><BR></FONT>I expected to get a number of rows corresponding to the total number of order-details in the database.&nbsp; But I didn't.&nbsp; I got a whole lot less.&nbsp; So I started experimenting with different forms of the query.&nbsp; If I selected o.OrderID instead of d.ProductID, I got a different number from either of the other two. If I selected c.CustomerID, again an entirely different number of rows.&nbsp; It was only when I chose to select the entire order-detail object did I get the number of rows I was expecting. <BR><BR>Something strange seems to be going on.&nbsp; On nobody's definition of SQL should I be getting a different number of rows depending on the columns in the selection (except if that SELECT has a DISTINCT operator specified.)&nbsp; It was as if all queries were getting a default DISTINCT operation. When I took a look a the results when I selected out only ProductID, sure enough, all I got back were distinct product-id's.&nbsp; MySQL has an 'ALL' keyword that is the semantic opposite of DISTINCT, so I tried adding that to the query, but to no avail.&nbsp; <BR><BR>I don't know if this is a problem in the query engine or the transport layer, or if the MySQL folks actually think it is appropriate behavior.&nbsp; As far as I'm concerned it is catastrophically bad; E_FAIL. For this problem alone I would recommend not using MySQL. Still, it may not be as bad as it sounds. It is likely very rare that you'd ever actually write a query that was expected to retrieve duplicate rows of data. So it may not ever impact you at all. I do recommend testing all your queries (and your application) before you put it into production.</LI></UL>
<UL>
<LI><STRONG>SQLite</STRONG> - This is an open-source database product that is similar in nature to MS Access and SQL Compact, since it runs in-proc and is not really a server. After wrangling with MySQL, I thought I knew all I needed to know about different forms of SQL, until Jonathan Peppers sent me his go at making a SQLite provider. ( See, I told everyone that I'd add new providers if they would send them to me.)&nbsp; Of course, SQLite had a few problems of its own. <BR><BR>While MySQL has a huge library of function, SQLite has a tiny one; many .Net API's don't have supported translations.&nbsp; (This is of the set I had translated for MS SQL.&nbsp; To be truthful, MS Access falls short on some of these too.)&nbsp; So queries using API's other than some simple string manipulation or equality testing probably won't work against SQLite.&nbsp; <BR><BR>In addition one of SQLite's big drawbacks is its lack of a rich type system.&nbsp; SQLite's developers claim this to be a feature, and it may afford great flexibility, but is often a death sentence for LINQ queries, which are all strongly typed.&nbsp; SQLite does have types, but only a few of them, like number, text and binary.&nbsp; Problems arise when you try to use DateTime's, as they are not really their own type in SQLite, but a text layout.&nbsp; For example, if you were trying to find all orders for a customer that happen in January, you might write this query. <BR><BR><FONT color=#0000ff>from</FONT> o <FONT color=#0000ff>in</FONT> db.Orders <BR><FONT color=#0000ff>where</FONT> o.CustomerID == cust &amp;&amp; o.OrderDate.Month = 1 <BR><FONT color=#0000ff>select</FONT> o <BR><BR>this would produce this query. <BR><BR><FONT color=#008000>SELECT o.OrderID, o.OrderDate <BR>FROM Orders AS o <BR>WHERE o.CustomerID = @cust AND STRFTIME('%m', o.OrderDate) = 1 <BR></FONT><BR>The date function to extract the month out of the OrderDate column is really a text formatting function that extracts the month portion of the date-time text layout, which in this case is the text '01', since the date-time format is always padded to a specific width.&nbsp; When this is compared against the number (1), another subtle difference crops up. For all other SQL's I've come across, text is considered the weakest form of type, so when two types are compared for equality text is always converted to the other form.&nbsp; Yet, in SQLite, the opposite it true (which truthfully is more like C# and Java).&nbsp; So when the two types are compared they are found incompatible, because the number (1) is turned into the text '1' and that is not the same as the text '01'.&nbsp;Adding insult to injury, there appears to be no type conversion functions at all, so I can't even work around the problem by injecting a conversion. My ignorance of SQLite may just be showing here, or a lack of sufficient documentation.<BR><BR>So my recommendation if you are using SQLite, to stay away from most API functions in your where clauses and such. API calls in the projection are okay, because these get executed on the client. <BR></LI></UL>
<H3>Transactions</H3>
<BLOCKQUOTE>
<P>I'm surprised no one's called me on this before. The DbQueryProvider and its ilk have been suspiciously lacking in support for transactions. The providers work, LINQ queries are converted into ADO Commands and executed, yet those ADO Command objects are never assigned an ADO transaction, even if you started one explicitly.&nbsp; <BR><BR>Of course, the official word from Microsoft is to stop using the ADO transactions altogether and instead use the System.Transactions.TransactionScope object, that is newer, better and enables automatic use of distributed transactions, etc, etc, etc. And if you did use TransactionScope, then the problem I'm referring to would not be a problem. SqlCommand object's would implicitly enlist in the transation without me having to specify anything.&nbsp; <BR><BR>Unfortunately, TransactionScope is mired with many problems and is not supported by all ADO providers so ADO transactions are still a necessity.&nbsp; You can now use ADO transactions with query providers in a manner similar to LINQ to SQL. <BR><BR><FONT face="Courier New">provider.Transaction = provider.Connection.BeginTransaction(); <BR></FONT><FONT face="Courier New"><FONT color=#008000><BR>// use the provider here to execute queries and updates, etc. <BR></FONT><BR>provider.Transaction.Commit(); <BR>provider.Transaction = null; <BR></FONT><BR>The provider will use whatever transaction object you give it when it creates new ADO command objects.</P></BLOCKQUOTE>
<H3>Entity Providers</H3>
<BLOCKQUOTE>
<P>I decided to formalize the pairing of query providers with a Table object that enables updates and other facilities.&nbsp; The definition of an entity provider is now defined by these three interfaces.</P></BLOCKQUOTE>
<BLOCKQUOTE><PRE class=code><SPAN style="COLOR: blue">public interface </SPAN><SPAN style="COLOR: #2b91af">IEntityProvider </SPAN>: <SPAN style="COLOR: #2b91af">IQueryProvider
</SPAN>{
    <SPAN style="COLOR: #2b91af">IEntityTable</SPAN>&lt;T&gt; GetTable&lt;T&gt;(<SPAN style="COLOR: blue">string </SPAN>tableId);
    <SPAN style="COLOR: #2b91af">IEntityTable </SPAN>GetTable(<SPAN style="COLOR: #2b91af">Type </SPAN>type, <SPAN style="COLOR: blue">string </SPAN>tableId);
}

<SPAN style="COLOR: blue">public interface </SPAN><SPAN style="COLOR: #2b91af">IEntityTable </SPAN>: <SPAN style="COLOR: #2b91af">IQueryable</SPAN>, <SPAN style="COLOR: #2b91af">IUpdatable
</SPAN>{
    <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">IEntityProvider </SPAN>Provider { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: blue">string </SPAN>TableId { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: blue">object </SPAN>GetById(<SPAN style="COLOR: blue">object </SPAN>id);
    <SPAN style="COLOR: blue">int </SPAN>Insert(<SPAN style="COLOR: blue">object </SPAN>instance);
    <SPAN style="COLOR: blue">int </SPAN>Update(<SPAN style="COLOR: blue">object </SPAN>instance);
    <SPAN style="COLOR: blue">int </SPAN>Delete(<SPAN style="COLOR: blue">object </SPAN>instance);
    <SPAN style="COLOR: blue">int </SPAN>InsertOrUpdate(<SPAN style="COLOR: blue">object </SPAN>instance);
}

<SPAN style="COLOR: blue">public interface </SPAN><SPAN style="COLOR: #2b91af">IEntityTable</SPAN>&lt;T&gt; : <SPAN style="COLOR: #2b91af">IQueryable</SPAN>&lt;T&gt;, <SPAN style="COLOR: #2b91af">IEntityTable</SPAN>, <SPAN style="COLOR: #2b91af">IUpdatable</SPAN>&lt;T&gt;
{
    <SPAN style="COLOR: blue">new </SPAN>T GetById(<SPAN style="COLOR: blue">object </SPAN>id);
    <SPAN style="COLOR: blue">int </SPAN>Insert(T instance);
    <SPAN style="COLOR: blue">int </SPAN>Update(T instance);
    <SPAN style="COLOR: blue">int </SPAN>Delete(T instance);
    <SPAN style="COLOR: blue">int </SPAN>InsertOrUpdate(T instance);
}</PRE></BLOCKQUOTE><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A>
<BLOCKQUOTE>
<P>You can now always get to a table directly from a provider.&nbsp; The two concepts are coupled together.&nbsp; An entity table also has explicit CRUD methods and implements IUpdatable, so no more separation between normal tables and updatable tables. In my mind this simplifies things quite a bit.&nbsp; <BR><BR>Of course, this caused me to want to rename DbQueryProvider.&nbsp; Ooops.&nbsp; This will likely cause you some grief as any of your existing code that was using DbQueryProvider directly is now not going to compile.&nbsp; The new name for this class is now DbEntityProvider. It might not matter so much now that there is a nifty IEntityProvider interface.</P></BLOCKQUOTE>
<H3>Entity Sessions</H3>
<BLOCKQUOTE>
<P>One thing missing from the Toolkit so far has been all of that context stuff that LINQ to SQL and LINQ to Entities have.&nbsp; When you use LINQ to SQL you have a change tracking service that detects when your objects change, and sends the updates for you all at the same time when you call SubmitChanges.&nbsp; <BR><BR>An entity session is all of this change-tracking, deferred updating stuff packaged up together. It is distinctly different from an entity provider in these ways, yet similar to one in many others. <BR><BR>An entity session is defined below:</P></BLOCKQUOTE>
<BLOCKQUOTE><PRE class=code><SPAN style="COLOR: blue">public interface </SPAN><SPAN style="COLOR: #2b91af">IEntitySession
</SPAN>{
    <SPAN style="COLOR: #2b91af">IEntityProvider </SPAN>Provider { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: #2b91af">ISessionTable</SPAN>&lt;T&gt; GetTable&lt;T&gt;(<SPAN style="COLOR: blue">string </SPAN>tableId);
    <SPAN style="COLOR: #2b91af">ISessionTable </SPAN>GetTable(<SPAN style="COLOR: #2b91af">Type </SPAN>elementType, <SPAN style="COLOR: blue">string </SPAN>tableId);
    <SPAN style="COLOR: blue">void </SPAN>SubmitChanges();
}

<SPAN style="COLOR: blue">public interface </SPAN><SPAN style="COLOR: #2b91af">ISessionTable </SPAN>: <SPAN style="COLOR: #2b91af">IQueryable
</SPAN>{
    <SPAN style="COLOR: #2b91af">IEntitySession </SPAN>Session { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: #2b91af">IEntityTable </SPAN>ProviderTable { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: blue">object </SPAN>GetById(<SPAN style="COLOR: blue">object </SPAN>id);
    <SPAN style="COLOR: blue">void </SPAN>SetSubmitAction(<SPAN style="COLOR: blue">object </SPAN>instance, <SPAN style="COLOR: #2b91af">SubmitAction </SPAN>action);
    <SPAN style="COLOR: #2b91af">SubmitAction </SPAN>GetSubmitAction(<SPAN style="COLOR: blue">object </SPAN>instance);
}

<SPAN style="COLOR: blue">public interface </SPAN><SPAN style="COLOR: #2b91af">ISessionTable</SPAN>&lt;T&gt; : <SPAN style="COLOR: #2b91af">IQueryable</SPAN>&lt;T&gt;, <SPAN style="COLOR: #2b91af">ISessionTable
</SPAN>{
    <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">IEntityTable</SPAN>&lt;T&gt; ProviderTable { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: blue">new </SPAN>T GetById(<SPAN style="COLOR: blue">object </SPAN>id);
    <SPAN style="COLOR: blue">void </SPAN>SetSubmitAction(T instance, <SPAN style="COLOR: #2b91af">SubmitAction </SPAN>action);
    <SPAN style="COLOR: #2b91af">SubmitAction </SPAN>GetSubmitAction(T instance);
}

<SPAN style="COLOR: blue">public enum </SPAN><SPAN style="COLOR: #2b91af">SubmitAction
</SPAN>{
    None,
    Update,
    PossibleUpdate,
    Insert,
    InsertOrUpdate,
    Delete
}

<SPAN style="COLOR: blue">public static class </SPAN><SPAN style="COLOR: #2b91af">SessionTableExtensions
</SPAN>{
    <SPAN style="COLOR: blue">public static void </SPAN>InsertOnSubmit&lt;T&gt;(<SPAN style="COLOR: blue">this </SPAN><SPAN style="COLOR: #2b91af">ISessionTable</SPAN>&lt;T&gt; table, T instance)
    {
        table.SetSubmitAction(instance, <SPAN style="COLOR: #2b91af">SubmitAction</SPAN>.Insert);
    }

    <SPAN style="COLOR: blue">public static void </SPAN>InsertOnSubmit(<SPAN style="COLOR: blue">this </SPAN><SPAN style="COLOR: #2b91af">ISessionTable </SPAN>table, <SPAN style="COLOR: blue">object </SPAN>instance)
    {
        table.SetSubmitAction(instance, <SPAN style="COLOR: #2b91af">SubmitAction</SPAN>.Insert);
    }

    <SPAN style="COLOR: blue">public static void </SPAN>InsertOrUpdateOnSubmit&lt;T&gt;(<SPAN style="COLOR: blue">this </SPAN><SPAN style="COLOR: #2b91af">ISessionTable</SPAN>&lt;T&gt; table, T instance)
    {
        table.SetSubmitAction(instance, <SPAN style="COLOR: #2b91af">SubmitAction</SPAN>.InsertOrUpdate);
    }

    <SPAN style="COLOR: blue">public static void </SPAN>InsertOrUpdateOnSubmit(<SPAN style="COLOR: blue">this </SPAN><SPAN style="COLOR: #2b91af">ISessionTable </SPAN>table, <SPAN style="COLOR: blue">object </SPAN>instance)
    {
        table.SetSubmitAction(instance, <SPAN style="COLOR: #2b91af">SubmitAction</SPAN>.InsertOrUpdate);
    }

    <SPAN style="COLOR: blue">public static void </SPAN>UpdateOnSubmit&lt;T&gt;(<SPAN style="COLOR: blue">this </SPAN><SPAN style="COLOR: #2b91af">ISessionTable</SPAN>&lt;T&gt; table, T instance)
    {
        table.SetSubmitAction(instance, <SPAN style="COLOR: #2b91af">SubmitAction</SPAN>.Update);
    }

    <SPAN style="COLOR: blue">public static void </SPAN>UpdateOnSubmit(<SPAN style="COLOR: blue">this </SPAN><SPAN style="COLOR: #2b91af">ISessionTable </SPAN>table, <SPAN style="COLOR: blue">object </SPAN>instance)
    {
        table.SetSubmitAction(instance, <SPAN style="COLOR: #2b91af">SubmitAction</SPAN>.Update);
    }

    <SPAN style="COLOR: blue">public static void </SPAN>DeleteOnSubmit&lt;T&gt;(<SPAN style="COLOR: blue">this </SPAN><SPAN style="COLOR: #2b91af">ISessionTable</SPAN>&lt;T&gt; table, T instance)
    {
        table.SetSubmitAction(instance, <SPAN style="COLOR: #2b91af">SubmitAction</SPAN>.Delete);
    }

    <SPAN style="COLOR: blue">public static void </SPAN>DeleteOnSubmit(<SPAN style="COLOR: blue">this </SPAN><SPAN style="COLOR: #2b91af">ISessionTable </SPAN>table, <SPAN style="COLOR: blue">object </SPAN>instance)
    {
        table.SetSubmitAction(instance, <SPAN style="COLOR: #2b91af">SubmitAction</SPAN>.Delete);
    }
}</PRE></BLOCKQUOTE><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A>
<BLOCKQUOTE>
<P>As you can see, an entity session has tables, just like a provider.&nbsp; Yet, those tables are not directly updatable.&nbsp; Instead you can assign entity instances submit actions. These are the actions that take place later when you call SubmitChanges.&nbsp; There are a bunch of extension methods defined to add the LINQ to SQL like InsertOnSubmit() methods to the interface.&nbsp; These simply call the SetSubmitAction() method for you. <BR><BR>Also note that a session is not a provider. It is a service used in conjunction with a provider. You can use multiple different sessions with the same provider instance.&nbsp;&nbsp;&nbsp; <BR><BR>There is one current implementation of an entity session in the Toolkit called (you guessed it) DbEntitySession.&nbsp; You create a DbEntitySession by giving it an existing DbEntityProvider. The DbEntitySession hooks the provider in such a way that it gets first crack at all materialized objects before they are returned to you. In this way, the DbEntitySession can employ an identity cache so queries that retrieve the same entity will always return the same entity instance, and it can start automatic change tracking on all entities returned. <BR><BR>You are also not locked into the session's behavior.&nbsp; At any time you can interact with the underlying provider instead for retrieving entities without passing through the identity cache or being changed tracked.&nbsp; You can even get to the provider's table directly off a session table.</P></BLOCKQUOTE>
<H3>Provider Factory</H3>
<BLOCKQUOTE>
<P>Now with so many providers and one single way to write queries you'd think it would be easy to switch between them.&nbsp; In reality it is not. You have to pick the provider you want, reference its library (IQToolkit.Data.XXX), reference its corresponding ADO library (System.Data.XXX), create the ADO connection, the mapping object and construct the provider. <BR><BR><FONT face="Courier New"><FONT color=#0000ff>var</FONT> connection = <FONT color=#0000ff>new</FONT> <FONT color=#008080>SqlConnection</FONT>(<FONT color=#800000>"..."</FONT>); <BR><FONT color=#0000ff>var</FONT> mapping = <FONT color=#0000ff>new</FONT> <FONT color=#008080>AttributeMapping</FONT>(<FONT color=#0000ff>typeof</FONT>(<FONT color=#008080>Northwind</FONT>)); <BR><FONT color=#0000ff>var</FONT> provider = <FONT color=#0000ff>new</FONT> <FONT color=#008080>SqlProvider</FONT>(connection, mapping, <FONT color=#008080>QueryPolicy</FONT>.Default, <FONT color=#0000ff>null</FONT>); <BR><FONT color=#0000ff>var</FONT> db = <FONT color=#0000ff>new</FONT> <FONT color=#008080>Northwind</FONT>(provider); <BR></FONT><BR>You can hide this all inside your database context class (or whatever you want to call yours), so you only have to write it once, but then your context class is tied to a specific provider.&nbsp; Instead, you could wrap this code up into a factory method of your own devising, but then calls to the factory would be spread throughout your codebase.&nbsp; There no good way to defer all this work to some configuration setting. Until now. <BR><BR>Introducing the new factory methods built into DbEntityProvider.</P><PRE class=code><SPAN style="COLOR: blue">public static </SPAN><SPAN style="COLOR: #2b91af">DbEntityProvider </SPAN>FromApplicationSettings();<BR>
<SPAN style="COLOR: blue">public static </SPAN><SPAN style="COLOR: #2b91af">DbEntityProvider </SPAN>From(<SPAN style="COLOR: blue">string </SPAN>filename, <SPAN style="COLOR: blue">string </SPAN>mappingId);

<SPAN style="COLOR: blue">public static </SPAN><SPAN style="COLOR: #2b91af">DbEntityProvider </SPAN>From(<SPAN style="COLOR: blue">string </SPAN>provider, <SPAN style="COLOR: blue">string </SPAN>connectionString, <SPAN style="COLOR: blue">string </SPAN>mappingId);</PRE><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A></BLOCKQUOTE>
<BLOCKQUOTE>
<P>These methods allow you to get up and running with only knowing a few bits of information.&nbsp; You don't have to hard link you application to any particular provider. <BR><BR>The <EM>FromApplicationSettings</EM> method creates you a new instance of a provider from information found in the config file.&nbsp; It looks for the "Provider", "Connection" and "Mapping" properties in the configuration and feeds them to the other factories.&nbsp; It is also possible to look this information up in web settings, but I have not formalized that one yet. <BR><BR>The <EM>provider</EM> argument is a string that refers to the name of an assembly that contains the query provider.&nbsp; These are generally of the form IQToolkit.Data.XXX.&nbsp; If that assembly is not loaded, it will be loaded dynamically. This assembly can be in the assembly cache or in the same directory as your app (or other places that the runtime might look.)&nbsp; From this assembly it will look for a type in the same namespace (as the name of the assembly) that derives from DbEntityProvider. <BR><BR>The <EM>connectionString</EM> and <EM>filename</EM> arguments are really the same thing. You can specify either the name of a database file or a full ADO connection string. If a file is specified, a correct connection string is obtained by calling the static GetConnectionString(string) method on the provider. A provider may be inferred from the file extension of a database file if none is specified. <BR><BR>The <EM>mappingId</EM> can either refer to the name of a context class (like Northwind) that has mapping attributes on it or the name of an xml file.&nbsp; <BR><BR>So now you can write code like this to get your provider. <BR><BR><FONT face="Courier New"><FONT color=#0000ff>var</FONT> db = <FONT color=#0000ff>new</FONT> <FONT color=#008080>Northwind</FONT>(<FONT color=#008080>DbEntityProvider</FONT>.From(somedbfile, somemapfile)); <BR><BR></FONT>Or better yet, you can use the FromApplicationSettings() method in the constructor of your context and still be configurable at runtime.</P></BLOCKQUOTE>
<H3>Madness</H3>
<BLOCKQUOTE>
<P>Of course, it wouldn't be a new toolkit release without some additional crazy changes.&nbsp; One significant change is namespaces again. This time its not going to conflict with your code too much.&nbsp; Most of the classes that where in IQToolkit.Data have been demoted into the namespace IQToolkit.Data.Common.&nbsp; This includes most all classes that are implementation detail or base classes.&nbsp; Mapping attributes and the like are now in IQToolkit.Data.Mapping.&nbsp; This makes the namespace clean and obvious when you start looking for things via intellisense.&nbsp; <BR><BR>DbEntityProvider and DbEntitySession are the only classes sitting in IQToolkit.Data, as these are the ones you'll likely need to reference when writing code.&nbsp; IEntityProvider and IEntitySession are in IQToolkit namespace, because they are not specific to ADO (System.Data classes).</P></BLOCKQUOTE>
<P><BR>I hope you find this version feature rich enough to either build application directly on top of it, or model your own provider or data layer by using these techniques.</P>
<P>Don't forget the audio tapes.</P>
<P mce_keep="true">&nbsp;</P><FONT face="Courier New"></FONT>]]></content:encoded>
    </item>
    <item>
      <title>Building a LINQ IQueryable provider - Part XIV</title>
      <link>https://docs.microsoft.com/archive/blogs/mattwar/building-a-linq-iqueryable-provider-part-xiv</link>
      <pubDate>Wed, 08 Apr 2009 19:21:00 GMT</pubDate>
      <dc:creator><![CDATA[Matt Warren - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mattwar/2009/04/08/building-a-linq-iqueryable-provider-part-xiv/</guid>
      <description><![CDATA[This is the fourteenth in a series of posts on how to build a LINQ IQueryable provider. If you have...]]></description>
      <content:encoded><![CDATA[<P>This is the <EM>fourteenth </EM>in a series of posts on how to build a LINQ IQueryable provider. If you have not read the previous posts you might request a weeks vacation, sit back, relax with a mochacino in one hand a netbook in the other, or if you've got better things to do with your time print them all out and stuff them under your pillow. Who knows, it might work better.</P>
<P><A href="http://blogs.msdn.com/mattwar/pages/linq-links.aspx" mce_href="http://blogs.msdn.com/mattwar/pages/linq-links.aspx">Complete list of posts in the Building an IQueryable Provider series</A></P>
<P>Okay, enough with all the post-is-late guilt! It's done now, so breathe a sigh of relief and get on with the reading.</P>
<P><STRONG>What's inside:</STRONG></P>
<BLOCKQUOTE>
<P><STRONG>More Mapping </STRONG>- Finally a real mapping system, with attributes and XML.</P>
<P><STRONG>More Providers</STRONG> - MS Access and MS SQL Server Compact Edition</P>
<P><STRONG>More POCO </STRONG>- Constructors, Enum and Interfaces.</P>
<P><STRONG>More More More</STRONG></P></BLOCKQUOTE>
<P>The full source code can be found at: </P>
<P><A href="http://www.codeplex.com/IQToolkit" mce_href="http://www.codeplex.com/IQToolkit">http://www.codeplex.com/IQToolkit</A> <BR></P>
<H3>More Mapping</H3>
<UL>
<LI><STRONG>Attribute Mapping</STRONG> - put attributes on the properties in the class that declares your tables. <BR><BR>This differs from LINQ to SQL mapping attributes which are placed on the entities themselves and is more like the proposed LINQ to Entity mapping attributes. However, I've not actually gone out of my way to make them the same. The advantages to this approach are 1) keeping the mapping separate from the entity objects (more POCO), and 2) being able to supply different mapping for the same entity type based on the table the entities are accessed from.&nbsp; <BR><BR>Mapping attributes look like this:</LI><PRE class=code>[<SPAN style="COLOR: #2b91af">Table</SPAN>]
[<SPAN style="COLOR: #2b91af">Column</SPAN>(Member = <SPAN style="COLOR: #a31515">"CustomerId"</SPAN>, IsPrimaryKey = <SPAN style="COLOR: blue">true</SPAN>)]
[<SPAN style="COLOR: #2b91af">Column</SPAN>(Member = <SPAN style="COLOR: #a31515">"ContactName"</SPAN>)]
[<SPAN style="COLOR: #2b91af">Column</SPAN>(Member = <SPAN style="COLOR: #a31515">"CompanyName"</SPAN>)]
[<SPAN style="COLOR: #2b91af">Column</SPAN>(Member = <SPAN style="COLOR: #a31515">"Phone"</SPAN>)]
[<SPAN style="COLOR: #2b91af">Column</SPAN>(Member = <SPAN style="COLOR: #a31515">"City"</SPAN>, DbType=<SPAN style="COLOR: #a31515">"NVARCHAR(20)"</SPAN>)]
[<SPAN style="COLOR: #2b91af">Column</SPAN>(Member = <SPAN style="COLOR: #a31515">"Country"</SPAN>)]
[<SPAN style="COLOR: #2b91af">Association</SPAN>(Member = <SPAN style="COLOR: #a31515">"Orders"</SPAN>, KeyMembers = <SPAN style="COLOR: #a31515">"CustomerID"</SPAN>, RelatedEntityID = <SPAN style="COLOR: #a31515">"Orders"</SPAN>, RelatedKeyMembers = <SPAN style="COLOR: #a31515">"CustomerID"</SPAN>)]
<SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">IUpdatableTable</SPAN>&lt;<SPAN style="COLOR: #2b91af">Customer</SPAN>&gt; Customers</PRE><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A></UL>
<BLOCKQUOTE>
<P>You specify the Table, Column and Association attributes as necessary.&nbsp; The 'Member' refers to the member in the entity type. If this is the same name as the database's column name you don't need to repeat it by specifying 'Name' too.&nbsp; <BR><BR>You can specify nested mapping information by using a dot in the Member name. This allows you to have what some call value types, but to keep from clashing with .Net terminology I don't. For example, if you've defined an Address type that you want to use in a nested relationship (actually embedded in the same table row) you can do that like this:</P><PRE class=code>[<SPAN style="COLOR: #2b91af">Table</SPAN>]
[<SPAN style="COLOR: #2b91af">Column</SPAN>(Member = <SPAN style="COLOR: #a31515">"EmployeeID"</SPAN>, IsPrimaryKey = <SPAN style="COLOR: blue">true</SPAN>)]
[<SPAN style="COLOR: #2b91af">Column</SPAN>(Member = <SPAN style="COLOR: #a31515">"LastName"</SPAN>)]
[<SPAN style="COLOR: #2b91af">Column</SPAN>(Member = <SPAN style="COLOR: #a31515">"FirstName"</SPAN>)]
[<SPAN style="COLOR: #2b91af">Column</SPAN>(Member = <SPAN style="COLOR: #a31515">"Title"</SPAN>)]
[<SPAN style="COLOR: #2b91af">Column</SPAN>(Member = <SPAN style="COLOR: #a31515">"Address.Street"</SPAN>, Name = <SPAN style="COLOR: #a31515">"Address"</SPAN>)]
[<SPAN style="COLOR: #2b91af">Column</SPAN>(Member = <SPAN style="COLOR: #a31515">"Address.City"</SPAN>)]
[<SPAN style="COLOR: #2b91af">Column</SPAN>(Member = <SPAN style="COLOR: #a31515">"Address.Region"</SPAN>)]
[<SPAN style="COLOR: #2b91af">Column</SPAN>(Member = <SPAN style="COLOR: #a31515">"Address.PostalCode"</SPAN>)]
<SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">IUpdatable</SPAN>&lt;<SPAN style="COLOR: #2b91af">Employee</SPAN>&gt; Employees</PRE></BLOCKQUOTE>
<UL>
<LI><STRONG>Xml Mapping</STRONG> -- this is same as attribute based mapping but data is read from an XML file.&nbsp; <BR><BR>Xml mapping looks like this:</LI><PRE class=code><SPAN style="COLOR: blue">&lt;?</SPAN><SPAN style="COLOR: #a31515">xml </SPAN><SPAN style="COLOR: red">version</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">1.0</SPAN>" <SPAN style="COLOR: red">encoding</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">utf-8</SPAN>" <SPAN style="COLOR: blue">?&gt;
&lt;</SPAN><SPAN style="COLOR: #a31515">map</SPAN><SPAN style="COLOR: blue">&gt;
  &lt;</SPAN><SPAN style="COLOR: #a31515">Entity </SPAN><SPAN style="COLOR: red">Id</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">Customers</SPAN>"<SPAN style="COLOR: blue">&gt;
    &lt;</SPAN><SPAN style="COLOR: #a31515">Table </SPAN><SPAN style="COLOR: red">Name</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">Customers</SPAN>" <SPAN style="COLOR: blue">/&gt;
    &lt;</SPAN><SPAN style="COLOR: #a31515">Column </SPAN><SPAN style="COLOR: red">Member </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">CustomerId</SPAN>" <SPAN style="COLOR: red">IsPrimaryKey </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">true</SPAN>" <SPAN style="COLOR: blue">/&gt;
    &lt;</SPAN><SPAN style="COLOR: #a31515">Column </SPAN><SPAN style="COLOR: red">Member </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">ContactName</SPAN>" <SPAN style="COLOR: blue">/&gt;
    &lt;</SPAN><SPAN style="COLOR: #a31515">Column </SPAN><SPAN style="COLOR: red">Member </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">CompanyName</SPAN>" <SPAN style="COLOR: blue">/&gt;
    &lt;</SPAN><SPAN style="COLOR: #a31515">Column </SPAN><SPAN style="COLOR: red">Member </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">Phone</SPAN>" <SPAN style="COLOR: blue">/&gt;
    &lt;</SPAN><SPAN style="COLOR: #a31515">Column </SPAN><SPAN style="COLOR: red">Member </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">City</SPAN>" <SPAN style="COLOR: red">DbType</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">NVARCHAR(20)</SPAN>" <SPAN style="COLOR: blue">/&gt;
    &lt;</SPAN><SPAN style="COLOR: #a31515">Column </SPAN><SPAN style="COLOR: red">Member </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">Country</SPAN>" <SPAN style="COLOR: blue">/&gt;
    &lt;</SPAN><SPAN style="COLOR: #a31515">Association </SPAN><SPAN style="COLOR: red">Member </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">Orders</SPAN>" <SPAN style="COLOR: red">KeyMembers </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">CustomerID</SPAN>" <SPAN style="COLOR: red">RelatedEntityID </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">Orders</SPAN>" <SPAN style="COLOR: red">RelatedKeyMembers </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">CustomerID</SPAN>" <SPAN style="COLOR: blue">/&gt;
  &lt;/</SPAN><SPAN style="COLOR: #a31515">Entity</SPAN><SPAN style="COLOR: blue">&gt;
  &lt;</SPAN><SPAN style="COLOR: #a31515">Entity </SPAN><SPAN style="COLOR: red">Id</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">Orders</SPAN>"<SPAN style="COLOR: blue">&gt;
    &lt;</SPAN><SPAN style="COLOR: #a31515">Column </SPAN><SPAN style="COLOR: red">Member </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">OrderID</SPAN>" <SPAN style="COLOR: red">IsPrimaryKey </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">true</SPAN>" <SPAN style="COLOR: red">IsGenerated </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">true</SPAN>"<SPAN style="COLOR: blue">/&gt;
    &lt;</SPAN><SPAN style="COLOR: #a31515">Column </SPAN><SPAN style="COLOR: red">Member </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">CustomerID</SPAN>" <SPAN style="COLOR: blue">/&gt;
    &lt;</SPAN><SPAN style="COLOR: #a31515">Column </SPAN><SPAN style="COLOR: red">Member </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">OrderDate</SPAN>" <SPAN style="COLOR: blue">/&gt;
    &lt;</SPAN><SPAN style="COLOR: #a31515">Association </SPAN><SPAN style="COLOR: red">Member </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">Customer</SPAN>" <SPAN style="COLOR: red">KeyMembers </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">CustomerID</SPAN>" <SPAN style="COLOR: red">RelatedEntityID </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">Customers</SPAN>" <SPAN style="COLOR: red">RelatedKeyMembers </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">CustomerID</SPAN>" <SPAN style="COLOR: blue">/&gt;
    &lt;</SPAN><SPAN style="COLOR: #a31515">Association </SPAN><SPAN style="COLOR: red">Member </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">Details</SPAN>" <SPAN style="COLOR: red">KeyMembers </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">OrderID</SPAN>" <SPAN style="COLOR: red">RelatedEntityID </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">OrderDetails</SPAN>" <SPAN style="COLOR: red">RelatedKeyMembers </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">OrderID</SPAN>" <SPAN style="COLOR: blue">/&gt;
  &lt;/</SPAN><SPAN style="COLOR: #a31515">Entity</SPAN><SPAN style="COLOR: blue">&gt;
  &lt;</SPAN><SPAN style="COLOR: #a31515">Entity </SPAN><SPAN style="COLOR: red">Id</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">OrderDetails</SPAN>"<SPAN style="COLOR: blue">&gt;
    &lt;</SPAN><SPAN style="COLOR: #a31515">Table </SPAN><SPAN style="COLOR: red">Name</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">Order Details</SPAN>"<SPAN style="COLOR: blue">/&gt;
    &lt;</SPAN><SPAN style="COLOR: #a31515">Column </SPAN><SPAN style="COLOR: red">Member </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">OrderID</SPAN>" <SPAN style="COLOR: red">IsPrimaryKey </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">true</SPAN>" <SPAN style="COLOR: blue">/&gt;
    &lt;</SPAN><SPAN style="COLOR: #a31515">Column </SPAN><SPAN style="COLOR: red">Member </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">ProductID</SPAN>" <SPAN style="COLOR: red">IsPrimaryKey </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">true</SPAN>" <SPAN style="COLOR: blue">/&gt;
    &lt;</SPAN><SPAN style="COLOR: #a31515">Association </SPAN><SPAN style="COLOR: red">Member </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">Product</SPAN>" <SPAN style="COLOR: red">KeyMembers </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">ProductID</SPAN>" <SPAN style="COLOR: red">RelatedEntityID </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">Products</SPAN>" <SPAN style="COLOR: red">RelatedKeyMembers </SPAN><SPAN style="COLOR: blue">= </SPAN>"<SPAN style="COLOR: blue">ProductID</SPAN>" <SPAN style="COLOR: blue">/&gt;
  &lt;/</SPAN><SPAN style="COLOR: #a31515">Entity</SPAN><SPAN style="COLOR: blue">&gt;            
&lt;/</SPAN><SPAN style="COLOR: #a31515">map</SPAN><SPAN style="COLOR: blue">&gt;</SPAN></PRE></UL>
<BLOCKQUOTE>
<P>You use it like this:</P></BLOCKQUOTE>
<BLOCKQUOTE><PRE class=code><SPAN style="COLOR: #2b91af">XmlMapping </SPAN>mapping = <SPAN style="COLOR: #2b91af">XmlMapping</SPAN>.FromXml(<SPAN style="COLOR: #2b91af">TSqlLanguage</SPAN>.Default, <SPAN style="COLOR: #2b91af">File</SPAN>.ReadAllText(<SPAN style="COLOR: #a31515">@"northwind.xml"</SPAN>));
<SPAN style="COLOR: #2b91af">SqlQueryProvider </SPAN>provider = <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">SqlQueryProvider</SPAN>(connection, mapping);</PRE></BLOCKQUOTE>
<UL>
<LI><STRONG>Multi-table mapping</STRONG> -- Map multiple tables into a single entity.&nbsp; If you've got entity data spread out over multiple tables with a 1:1 association between them you can now specify the additional tables in mapping using the ExtensionTable attribute or equivalent XML element.&nbsp; <BR><BR>Here's what a multi-table mapping looks like:</LI><PRE class=code>[<SPAN style="COLOR: #2b91af">Table</SPAN>(Name = <SPAN style="COLOR: #a31515">"TestTable1"</SPAN>, Alias = <SPAN style="COLOR: #a31515">"TT1"</SPAN>)]
[<SPAN style="COLOR: #2b91af">ExtensionTable</SPAN>(Name = <SPAN style="COLOR: #a31515">"TestTable2"</SPAN>, Alias = <SPAN style="COLOR: #a31515">"TT2"</SPAN>, KeyColumns = <SPAN style="COLOR: #a31515">"ID"</SPAN>, RelatedAlias = <SPAN style="COLOR: #a31515">"TT1"</SPAN>, RelatedKeyColumns = <SPAN style="COLOR: #a31515">"ID"</SPAN>)]
[<SPAN style="COLOR: #2b91af">ExtensionTable</SPAN>(Name = <SPAN style="COLOR: #a31515">"TestTable3"</SPAN>, Alias = <SPAN style="COLOR: #a31515">"TT3"</SPAN>, KeyColumns = <SPAN style="COLOR: #a31515">"ID"</SPAN>, RelatedAlias = <SPAN style="COLOR: #a31515">"TT1"</SPAN>, RelatedKeyColumns = <SPAN style="COLOR: #a31515">"ID"</SPAN>)]
[<SPAN style="COLOR: #2b91af">Column</SPAN>(Member = <SPAN style="COLOR: #a31515">"ID"</SPAN>, Alias = <SPAN style="COLOR: #a31515">"TT1"</SPAN>, IsPrimaryKey = <SPAN style="COLOR: blue">true</SPAN>, IsGenerated = <SPAN style="COLOR: blue">true</SPAN>)]
[<SPAN style="COLOR: #2b91af">Column</SPAN>(Member = <SPAN style="COLOR: #a31515">"Value1"</SPAN>, Alias = <SPAN style="COLOR: #a31515">"TT1"</SPAN>)]
[<SPAN style="COLOR: #2b91af">Column</SPAN>(Member = <SPAN style="COLOR: #a31515">"Value2"</SPAN>, Alias = <SPAN style="COLOR: #a31515">"TT2"</SPAN>)]
[<SPAN style="COLOR: #2b91af">Column</SPAN>(Member = <SPAN style="COLOR: #a31515">"Value3"</SPAN>, Alias = <SPAN style="COLOR: #a31515">"TT3"</SPAN>)]
<SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">IUpdatable</SPAN>&lt;<SPAN style="COLOR: #2b91af">MultiTableEntity</SPAN>&gt; MultiTableEntities</PRE><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A></UL>
<BLOCKQUOTE>
<P>Extension tables are specified similar to how Associations are specified, except you are never referring to members, only column names.&nbsp; You use the 'Alias' value to connect column &amp; association mappings with columns from particular tables.&nbsp; All queries for this multi-table entity treat the 'Table' as the primary table queried, all other tables are queried with left-outer joins.&nbsp; All keys for associations must be from the same alias. <BR><BR>Can I mix nested mapping with multi-table mapping?&nbsp; I have not tried it, but in theory it should work. It should not matter which table your nested entity gets it's data from, so in effect you can have a composition relationship between one table and another as long as it is 1:1.&nbsp;&nbsp; </P></BLOCKQUOTE>
<BLOCKQUOTE>
<P><STRONG>What about many-to-many?</STRONG>&nbsp; Not yet. Making the system query a many-to-many relationship is relatively easy.&nbsp; I haven't yet figured out the right semantics for inserts &amp; updates. Right now, all insert, updates and deletes are explicit via calls to the IUpdatable with real-live entities. Yet how do you make an explicit update to the link table that you don't have an entity directly mapped to?&nbsp; I need to ponder this some more.&nbsp; Possibly if one side of the relationship is a composition as opposed to an association, then it would be implied when that side is updated.&nbsp; Yet what if you chose not to load the relationship, how do you tell the system to not delete all previous relationships?</P></BLOCKQUOTE>
<H3>More Providers</H3>
<UL>
<LI><STRONG>MS Access</STRONG> -- This new query provider works with both Access 2000 - 2003 and Access 2007 data files. I don't know what the true differences are between the Jet and the Ace engines; the query language appears to be identical (as per my limited tests so far), yet the filename extension changed in Access 2007 to 'accdb' instead of 'mdb' and the northwind sample database plumped up an extra 66% in disk size without any additional data.</LI></UL>
<BLOCKQUOTE>
<P>In order to make this work I've added an AccessLanguage object that is necessary to get the correct semantics for MS Access queries and an AccessFormatter object that handles generating the correct command text. In order to salvage as much as I could from the TSqlFormatter, I moved most of this code to a common SqlFormatter base class, and now the TSQL and Access formatters only supply the deviations from the standard syntax.&nbsp; (Of course, 'standard' is currently whatever I deem it to be so don't go getting some actual online specification and prove me wrong.) Access only allows one command at a time, so that added an extra wrinkle, but in the end there is now support in the system for providers that can only do one command at a time. This means there are multiple round-trips to the engine for things like inserting a record and getting back the computed keys. Luckily, the access engine is in-proc so this is not really a burden. A new property on QueryLanguage, 'AllowMultipleCommands' determines how the execution plan is generated and whether multiple commands can be lumped together into a single ADO command. <BR><BR>The good news is that the access engine passes almost all the Northwind tests; some are not possible (mostly ones testing translation of framework methods that have no apparent equivalent in the access expression engine).&nbsp; There were a lot of hairy strange &amp; subtle differences in syntax between Access and TSQL, but most were handled by having different format rules, some required new expression visitors to change the query tree, like no explicit cross joins!&nbsp; This caused me to write a visitor to attempt to get rid of cross joins (often injected by my visitor that tries to get rid of cross-apply joins) which is now generally useful to everyone, and if that didn't do it, another visitor that would attempt to isolate out the cross joins from any other joins and push them into sub-queries where Access lets me use the old-style comma-list, which is truly a cross join, though it just can't be mixed with other kinds of joins in the same from clause.</P></BLOCKQUOTE>
<UL>
<LI><STRONG>SQL Compact</STRONG> -- Yes, even more SQL Server.&nbsp; Though to be truthful, SQL Server Compact Edition (aka SQL CE, aka SQL Compact, aka Skweelzy) is not really SQL Server, it is some other entirely different product that handles a subset of TSQL syntax, and is not a server at all since it runs in-proc just like MS Access.<BR><BR></LI>
<LI><STRONG>What about MySQL or Oracle? <BR></STRONG>One day. The fact is that MS SQL and MS Access are easy for me to get to, they are already on my box. Getting something else up and running would take actual effort, and the MS secret database police might come get me. Meanwhile, if someone out there wants to put together a provider implementation I'll add it into the drop. <BR><BR></LI>
<LI><STRONG>Where did the SqlQueryProvider go? <BR></STRONG>I moved it. With the addition of the new providers it became apparent that I'd have to start factoring out all this ADO provider specific nonsense, otherwise all uses of the toolkit would have direct dependencies to way more than necessary. So I made separate projects, each building its own library. I may end up separating all the core 'data' stuff out into its own project too. <BR><BR>The solution builds these libraries now:</LI></UL>
<BLOCKQUOTE>
<P>- <STRONG>IQToolkit.dll</STRONG> <BR>- <STRONG>IQToolkit.Data.Access.dll <BR></STRONG>- <STRONG>IQToolkit.Data.SqlClient.dll <BR></STRONG>- <STRONG>IQToolkit.Data.SqlServerCe.dll</STRONG></P></BLOCKQUOTE>
<H3>More POCO</H3>
<UL>
<LI><STRONG>Constructors</STRONG> -- Use entities that don't have default constructors.&nbsp; It is now possible to have entities that require invocation of a constructor with parameters.&nbsp; The binding process will figure out how to call your constructor and the client side code will call it for you as long as the constructor parameter names match property names. You can even have fully read-only entities if all data member are accounted for in the constructor. <BR><BR></LI>
<LI><STRONG>Enums</STRONG> -- They actually sort of work now. You can have a member in your entity typed as some enum and you get automatic mapping between that enum and a numeric type in the database. <BR><BR></LI>
<LI><STRONG>Interfaces and abstract base classes</STRONG> -- You can now declare you IQueryable's as IQueryable&lt;SomeInterface&gt; or IQueryable&lt;SomeAbstractClass&gt; and have the provider create instances of a compatible type under the covers, automatically translating all your references to interface or abstract class members to the appropriate mapped members. You <EM>can</EM> have mutiple entities share a common interface or base class and get different mapping for each. You <EM>can</EM> write code using generics and constrain generic parameters based on an interface and write queries that will get correct translation at runtime.&nbsp; (Note, variation of mapping likely won't work with compiled queries, since the translation is fixed on the first execution.) <BR></LI></UL>
<H3>Less Policy</H3>
<BLOCKQUOTE>
<P>There's not a whole lot of policy being used right now and the policy objects dependence on the mapping object was no where near as deep as the mapping object's dependence on the language.&nbsp; So policy is now independent of mapping, which means you can construct providers without specifying policy and/or reusing mapping with different policies.&nbsp; Now if I could only make it simpler to specify/construct mapping without needing to know the language.&nbsp; Back to the drawing board.</P></BLOCKQUOTE>
<H3>More Insanity</H3>
<BLOCKQUOTE>
<P>I apologize for the churn. The namespace changed so now all heck is going to break loose. Gone is the simple 'IQ' namespace and in its place is the 'IQToolkit' namespace.&nbsp; I really did like the 'IQ' name, it was short, classy and made you feel intelligent just by looking at it.&nbsp; Yet, it was hard to guess at if you did not already know what it was.&nbsp; I chose to change the namespace name to match the product name and the DLL name. You add reference to the IQToolkit.dll and you import/use the IQToolkit namespace. No fuss, no muss.&nbsp; Except for all those files you'll have to edit now. But hey, this is pre-pre-pre-pre beta stuff. Some people may think they are something special by snarkily keeping all their products in beta. They've got a lot to learn. </P></BLOCKQUOTE>
<P>I hope this toolkit is becoming useful to many. I realize there have been a variety of requests for new things in the toolkit that I just have not gotten time to put in yet.&nbsp; So you can expect plenty more in the future.</P>
<P>So enough with reading.&nbsp; It's time to code!</P>]]></content:encoded>
    </item>
    <item>
      <title>Building a LINQ IQueryable Provider - Part XIII</title>
      <link>https://docs.microsoft.com/archive/blogs/mattwar/building-a-linq-iqueryable-provider-part-xiii</link>
      <pubDate>Thu, 22 Jan 2009 13:59:00 GMT</pubDate>
      <dc:creator><![CDATA[Matt Warren - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mattwar/2009/01/22/building-a-linq-iqueryable-provider-part-xiii/</guid>
      <description><![CDATA[This is the thirteenth in a series of posts on how to build a LINQ IQueryable provider. If you have...]]></description>
      <content:encoded><![CDATA[<P>This is the <I>thirteenth </I>in a series of posts on how to build a LINQ IQueryable provider. If you have not read the previous posts you probably have a life beyond the keyboard, but if you don't then follow the link below to find oodles more to help fill your meaningless existence.</P>
<P><A href="http://blogs.msdn.com/mattwar/pages/linq-links.aspx" mce_href="http://blogs.msdn.com/mattwar/pages/linq-links.aspx">Complete list of posts in the Building an IQueryable Provider series</A></P>
<P>It's been precisely the correct amount of time that it took for me to complete the additional goodness that is jam packed into this drop, less actual work, dinners out, dinners in, any interesting film and televisions programs, housework, trips out to the store, family game night, time reading fiction, napping on the couch and other assorted unavoidable activities.</P>
<P>The full source code can be found at:</P>
<P><A href="http://www.codeplex.com/IQToolkit" mce_href="http://www.codeplex.com/IQToolkit">http://www.codeplex.com/IQToolkit</A></P>
<P>I'll try to cover as much as I can in this post, however you'll like find other gems by scouring the source itself.</P>
<P>What's inside:</P>
<BLOCKQUOTE>
<P><STRONG>Updates </STRONG>- Insert, Update &amp; Delete operations. </P>
<P><STRONG>Batch processing</STRONG> - true SQL Server batch processing.</P>
<P><STRONG>Server language type systems</STRONG> - correct parameter types.</P>
<P><STRONG>Mapping Changes</STRONG> - use the same class with multiple tables, etc. <BR></P></BLOCKQUOTE>
<H2>Insert, Update and Delete</H2>
<P>It's about time that this toolkit actually got usable right out of the box.&nbsp; My original intention with the series was to show how to build an IQueryable provider and that turned more and more into a fully working query engine that you could actually use to get real work done. Yet, how many real world applications only ever need to pull data out of a database and never push it back?&nbsp; Not many.</P>
<P>So I knew I'd eventually want to add updates, because I knew that you'd eventually need to do it too. Yet, every time I started thinking about updates I always fell into the trap of thinking about full blown ORM's with object tracking, et al, and I did not really want to go there, at least not yet. As a toolkit I think its just fine to define the primitives that a more advanced system might be built out of. And there is nothing wrong with those primitives being generally useful on their own. So you should be able to use the toolkit as-is and not only get a pretty good query engine but also something that at least works as a rudimentary data access layer.</P>
<H3>Common Primitives</H3>
<P>So then I set about thinking about just the primitives for updating data. They should have semantics similar to the underlying SQL equivalent commands. That means they should not defer work until some time later, but execute immediately. There should be at least the familiar commands, Insert, Update and Delete; but also Upsert (both Insert &amp; Update combined) since its so often the right thing for many situations.</P>
<P>Also, like other LINQ operations, update commands should be a pattern, and be available for any kind of provider. So I set out thinking about what the pattern would look like and how it might be specified.&nbsp; This is what I came up with.</P><PRE class=code><SPAN style="COLOR: blue">public interface </SPAN><SPAN style="COLOR: #2b91af">IUpdatable </SPAN>: <SPAN style="COLOR: #2b91af">IQueryable
</SPAN>{
}

<SPAN style="COLOR: blue">public interface </SPAN><SPAN style="COLOR: #2b91af">IUpdatable</SPAN>&lt;T&gt; : <SPAN style="COLOR: #2b91af">IUpdatable</SPAN>, <SPAN style="COLOR: #2b91af">IQueryable</SPAN>&lt;T&gt;
{
}

<SPAN style="COLOR: blue">public static class </SPAN><SPAN style="COLOR: #2b91af">Updatable
</SPAN>{
<SPAN style="COLOR: blue">    public static </SPAN>S Insert&lt;T, S&gt;(<SPAN style="COLOR: blue">this </SPAN><SPAN style="COLOR: #2b91af">IUpdatable</SPAN>&lt;T&gt; collection, T instance, <SPAN style="COLOR: #2b91af">Expression</SPAN>&lt;<SPAN style="COLOR: #2b91af">Func</SPAN>&lt;T, S&gt;&gt; resultSelector)
<SPAN style="COLOR: blue">    public static </SPAN>S Update&lt;T, S&gt;(<SPAN style="COLOR: blue">this </SPAN><SPAN style="COLOR: #2b91af">IUpdatable</SPAN>&lt;T&gt; collection, T instance, <SPAN style="COLOR: #2b91af">Expression</SPAN>&lt;<SPAN style="COLOR: #2b91af">Func</SPAN>&lt;T, <SPAN style="COLOR: blue">bool</SPAN>&gt;&gt; updateCheck, <SPAN style="COLOR: #2b91af">Expression</SPAN>&lt;<SPAN style="COLOR: #2b91af">Func</SPAN>&lt;T, S&gt;&gt; resultSelector)
<SPAN style="COLOR: blue">    public static </SPAN>S InsertOrUpdate&lt;T, S&gt;(<SPAN style="COLOR: blue">this </SPAN><SPAN style="COLOR: #2b91af">IUpdatable</SPAN>&lt;T&gt; collection, T instance, <SPAN style="COLOR: #2b91af">Expression</SPAN>&lt;<SPAN style="COLOR: #2b91af">Func</SPAN>&lt;T, <SPAN style="COLOR: blue">bool</SPAN>&gt;&gt; updateCheck, <SPAN style="COLOR: #2b91af">Expression</SPAN>&lt;<SPAN style="COLOR: #2b91af">Func</SPAN>&lt;T, S&gt;&gt; resultSelector)
<SPAN style="COLOR: blue">    public static int </SPAN>Delete&lt;T&gt;(<SPAN style="COLOR: blue">this </SPAN><SPAN style="COLOR: #2b91af">IUpdatable</SPAN>&lt;T&gt; collection, T instance, <SPAN style="COLOR: #2b91af">Expression</SPAN>&lt;<SPAN style="COLOR: #2b91af">Func</SPAN>&lt;T, <SPAN style="COLOR: blue">bool</SPAN>&gt;&gt; deleteCheck)
<SPAN style="COLOR: blue">    public static int </SPAN>Delete&lt;T&gt;(<SPAN style="COLOR: blue">this </SPAN><SPAN style="COLOR: #2b91af">IUpdatable</SPAN>&lt;T&gt; collection, <SPAN style="COLOR: #2b91af">Expression</SPAN>&lt;<SPAN style="COLOR: #2b91af">Func</SPAN>&lt;T, <SPAN style="COLOR: blue">bool</SPAN>&gt;&gt; predicate)
<SPAN style="COLOR: blue">    public static </SPAN><SPAN style="COLOR: #2b91af">IEnumerable</SPAN>&lt;S&gt; Batch&lt;T,S&gt;(<SPAN style="COLOR: blue">this </SPAN><SPAN style="COLOR: #2b91af">IUpdatable </SPAN>collection, <SPAN style="COLOR: #2b91af">IEnumerable</SPAN>&lt;T&gt; instances, <SPAN style="COLOR: #2b91af">Expression</SPAN>&lt;<SPAN style="COLOR: #2b91af">Func</SPAN>&lt;T, S&gt;&gt; fnOperation, <SPAN style="COLOR: blue">int </SPAN>batchSize, <SPAN style="COLOR: blue">bool </SPAN>stream)<BR>    ...
}</PRE><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A>
<P>This pattern works just like the LINQ Enumerable and Queryable patterns.&nbsp; I've declared an interface 'IUpdatable' that extends IQueryable, so anything that is updatable is also queryable, and then an Updatable class with a bunch of new extension methods that encapsulate the pattern.&nbsp; (I realize the IUpdatable name may be in conflict with some other library, but until I think of something better this is what it is.)</P>
<P>The Insert method inserts an object instance into a collection. It's not an ordinary insert, like with List&lt;T&gt;. The collection is considered to be remote and inserting into it copies the data from your instance. It has an optional result-selector argument that can be a function you supply to construct a result out of the object after it has been inserted. This, of course, is intended to occur on the server and can be used to read back auto-generated state and computed expressions.</P><PRE class=code><SPAN style="COLOR: #2b91af">IUpdatable</SPAN>&lt;<SPAN style="COLOR: #2b91af">Customer</SPAN>&gt; customers = ...;
<SPAN style="COLOR: #2b91af">Customer </SPAN>c = ...;
customers.Insert(c);

<SPAN style="COLOR: #2b91af">IUpdatable</SPAN>&lt;<SPAN style="COLOR: #2b91af">Order</SPAN>&gt; orders = ...;
<SPAN style="COLOR: #2b91af">Order </SPAN>o = ...;
<SPAN style="COLOR: blue">var </SPAN>id = orders.Insert(o, d =&gt; d.OrderID);</PRE><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A>
<P>The Update method updates a corresponding object already in the collection with the values in the instance supplied. This is a complete overwrite, not a dynamic update like LINQ to SQL would have generated. I have not yet defined a piecemeal update operation, but I still can.&nbsp; We'll see how it goes.&nbsp; In addition to an update selector (like the one for insert) you can also specify an update-check predicate. This is an expression evaluated against the server's state and can be used to implement optimistic concurrency by basically checking to see if the server's state is still the same as you remembered it. An ORM layer built on top of this primitive might choose to generate this expression automatically, based on mapping information, but here you must specify it manually if you want to use it.</P><PRE class=code><SPAN style="COLOR: #2b91af">IUpdatable</SPAN>&lt;<SPAN style="COLOR: #2b91af">Customer</SPAN>&gt; customers = ...;
<SPAN style="COLOR: #2b91af">Customer </SPAN>c = ...;
<SPAN style="COLOR: blue">var </SPAN>computedValue = customers.Update(c, d =&gt; d.City == originalCity, d =&gt; d.ComputedColumn);<BR></PRE><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A>
<P>The InsertOrUpdate is the 'Upsert' operation.&nbsp; It will basically insert an object into the collection if a corresponding one does not exist, or update the one that does with the new values. You specify it just like you'd specify an update, instead you call InsertOrUpdate.</P>
<P>There are two flavors of Delete. The first one lets you delete the object in the collection corresponding to the instance. You can optionally specify a delete-check, which is similar to the update-check, a predicate function evaluated against the server's state. The delete will only occur if the check passes. The second flavor just lets you specify a predicate. It's basically a delete-all-where method and will delete all objects from the collection that match the predicate. So far, its the only SQL-like 'set-based' operation I've defined.</P><PRE class=code><SPAN style="COLOR: #2b91af">IUpdatable</SPAN>&lt;<SPAN style="COLOR: #2b91af">Customer</SPAN>&gt; customers = ...;
<SPAN style="COLOR: #2b91af">Customer </SPAN>c = ...;
customers.Delete(c, d =&gt; d.City == originalCity);

<SPAN style="COLOR: #2b91af">IUpdatable</SPAN>&lt;<SPAN style="COLOR: #2b91af">Customer</SPAN>&gt; customers = ...;
<SPAN style="COLOR: #2b91af">Customer </SPAN>c = ...;
customers.Delete(c =&gt; c.CustomerID == <SPAN style="COLOR: #a31515">"ALFKI"</SPAN>);</PRE>
<P>The last operation is Batch.&nbsp; It will allow you to specify an operation to apply to a whole set of instances. The operation can be one of the other commands like Insert or Update.&nbsp; You can use this method Insert, Update or Delete a whole bunch of objects all at the same time. If possible, the provider will use optimized batching techniques to give you extra performance.</P><PRE class=code><SPAN style="COLOR: #2b91af">IUpdatable</SPAN>&lt;<SPAN style="COLOR: #2b91af">Customer</SPAN>&gt; customers = ...;
<SPAN style="COLOR: #2b91af">Customer</SPAN>[] custs = <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">Customer</SPAN>[] { ... };

customers.Batch(custs, c =&gt; customers.Insert(c));</PRE>
<P>If you've got many objects to update and you want to have instance specific update-checks done, you can sneak the extra information into the batch process by combining the data together into a single collection and then piecing them apart in the operation.</P><PRE class=code><SPAN style="COLOR: #2b91af">IUpdatable</SPAN>&lt;<SPAN style="COLOR: #2b91af">Customer</SPAN>&gt; customers = ...;
<SPAN style="COLOR: blue">var </SPAN>oldAndNew = <SPAN style="COLOR: blue">new </SPAN>[] { <SPAN style="COLOR: blue">new </SPAN>{ Old = oldCustomer, New = newCustomer }, ...};
customers.Batch(oldAndNew, (u, x) =&gt; u.Update(x.New, d =&gt; d.City == x.Old.City));<BR>&nbsp;</PRE>
<H3>Updates and DbQueryProvider</H3>
<P>In order to make use of this new capability I'm going to need a new object to declare the IUpdatable interface.&nbsp; The Query&lt;T&gt; class only implemented IQueryable&lt;T&gt;, and that was fine as long as I only ever want to query.&nbsp; Now I also want to be able to update, so I need a new class to represent the root of my query that I can also update. These things in databases are called tables, so that's what I'll stick with.&nbsp; </P><PRE class=code><SPAN style="COLOR: blue">public interface </SPAN><SPAN style="COLOR: #2b91af">IQueryableTable </SPAN>: <SPAN style="COLOR: #2b91af">IQueryable
</SPAN>{
    <SPAN style="COLOR: blue">string </SPAN>TableID { <SPAN style="COLOR: blue">get</SPAN>; }
}

<SPAN style="COLOR: blue">public interface </SPAN><SPAN style="COLOR: #2b91af">IQueryableTable</SPAN>&lt;T&gt; : <SPAN style="COLOR: #2b91af">IQueryable</SPAN>&lt;T&gt;, <SPAN style="COLOR: #2b91af">IQueryableTable
</SPAN>{
}

<SPAN style="COLOR: blue">public class </SPAN><SPAN style="COLOR: #2b91af">QueryableTable</SPAN>&lt;T&gt; : <SPAN style="COLOR: #2b91af">Query</SPAN>&lt;T&gt;, <SPAN style="COLOR: #2b91af">IQueryableTable</SPAN>&lt;T&gt;
{
    <SPAN style="COLOR: blue">string </SPAN>id;

    <SPAN style="COLOR: blue">public </SPAN>QueryableTable(<SPAN style="COLOR: #2b91af">IQueryProvider </SPAN>provider, <SPAN style="COLOR: blue">string </SPAN>id)
        : <SPAN style="COLOR: blue">base</SPAN>(provider)
    {
        <SPAN style="COLOR: blue">this</SPAN>.id = id;
    }

    <SPAN style="COLOR: blue">public </SPAN>QueryableTable(<SPAN style="COLOR: #2b91af">IQueryProvider </SPAN>provider)
        : <SPAN style="COLOR: blue">this</SPAN>(provider, <SPAN style="COLOR: blue">null</SPAN>)
    {
    }

    <SPAN style="COLOR: blue">public string </SPAN>TableID
    {
        <SPAN style="COLOR: blue">get </SPAN>{ <SPAN style="COLOR: blue">return this</SPAN>.id; }
    }
}

<SPAN style="COLOR: blue">public interface </SPAN><SPAN style="COLOR: #2b91af">IUpdatableTable </SPAN>: <SPAN style="COLOR: #2b91af">IQueryableTable</SPAN>, <SPAN style="COLOR: #2b91af">IUpdatable
</SPAN>{
}

<SPAN style="COLOR: blue">public interface </SPAN><SPAN style="COLOR: #2b91af">IUpdatableTable</SPAN>&lt;T&gt; : <SPAN style="COLOR: #2b91af">IQueryableTable</SPAN>&lt;T&gt;, <SPAN style="COLOR: #2b91af">IUpdatable</SPAN>&lt;T&gt;, <SPAN style="COLOR: #2b91af">IUpdatableTable
</SPAN>{
}

<SPAN style="COLOR: blue">public class </SPAN><SPAN style="COLOR: #2b91af">UpdatableTable</SPAN>&lt;T&gt; : <SPAN style="COLOR: #2b91af">QueryableTable</SPAN>&lt;T&gt;, <SPAN style="COLOR: #2b91af">IUpdatableTable</SPAN>&lt;T&gt;
{
    <SPAN style="COLOR: blue">public </SPAN>UpdatableTable(<SPAN style="COLOR: #2b91af">IQueryProvider </SPAN>provider, <SPAN style="COLOR: blue">string </SPAN>id)
        : <SPAN style="COLOR: blue">base</SPAN>(provider, id)
    {
    }

    <SPAN style="COLOR: blue">public </SPAN>UpdatableTable(<SPAN style="COLOR: #2b91af">IQueryProvider </SPAN>provider)
        : <SPAN style="COLOR: blue">this</SPAN>(provider, <SPAN style="COLOR: blue">null</SPAN>)
    {
    }
}</PRE>
<P>You'll note that not only did I define a UpdatableTable&lt;T&gt; class, which is specifically what I wanted, I also went ahead and made a QueryableTable&lt;T&gt;, and extra interfaces to correspond to them.&nbsp; This is intentional.&nbsp; Eventually, I may want to add more methods specific to tables here and I'll need a place to put them.&nbsp; Right now I've only added a property 'TableID'.&nbsp; You can ignore it for now, though it will get more interesting when I discuss the mapping changes.</P>
<P>Take a look at the Northwind class in the test source code and you'll see how I made use of my new table class. <BR></P>
<H3>The Plumbing</H3>
<P>Of course, update commands work in the query provider just like queries do.&nbsp; First there are a bunch of new DbExpression nodes to represent them.</P><PRE class=code><SPAN style="COLOR: blue">public abstract class </SPAN><SPAN style="COLOR: #2b91af">CommandExpression </SPAN>: <SPAN style="COLOR: #2b91af">DbExpression
</SPAN>{
}<BR>
<SPAN style="COLOR: blue"><BR>public abstract class </SPAN><SPAN style="COLOR: #2b91af">CommandWithResultExpression </SPAN>: <SPAN style="COLOR: #2b91af">CommandExpression
</SPAN>{
    <SPAN style="COLOR: blue">public abstract </SPAN><SPAN style="COLOR: #2b91af">Expression </SPAN>Result { <SPAN style="COLOR: blue">get</SPAN>; }
}<BR>
<SPAN style="COLOR: blue">public class </SPAN><SPAN style="COLOR: #2b91af">InsertExpression </SPAN>: <SPAN style="COLOR: #2b91af">CommandWithResultExpression
</SPAN>{
    <SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">TableExpression </SPAN>Table { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">ReadOnlyCollection</SPAN>&lt;<SPAN style="COLOR: #2b91af">ColumnAssignment</SPAN>&gt; Assignments { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: blue">public override </SPAN><SPAN style="COLOR: #2b91af">Expression </SPAN>Result { <SPAN style="COLOR: blue">get</SPAN>; }
}

<SPAN style="COLOR: blue">public class </SPAN><SPAN style="COLOR: #2b91af">ColumnAssignment
</SPAN>{
    <SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">ColumnExpression </SPAN>Column { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">Expression </SPAN>Expression { <SPAN style="COLOR: blue">get</SPAN>; }
}

<SPAN style="COLOR: blue">public class </SPAN><SPAN style="COLOR: #2b91af">UpdateExpression </SPAN>: <SPAN style="COLOR: #2b91af">CommandWithResultExpression
</SPAN>{
    <SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">TableExpression </SPAN>Table { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">Expression </SPAN>Where { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">ReadOnlyCollection</SPAN>&lt;<SPAN style="COLOR: #2b91af">ColumnAssignment</SPAN>&gt; Assignments { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: blue">public override </SPAN><SPAN style="COLOR: #2b91af">Expression </SPAN>Result { <SPAN style="COLOR: blue">get</SPAN>; }
}

<SPAN style="COLOR: blue">public class </SPAN><SPAN style="COLOR: #2b91af">UpsertExpression </SPAN>: <SPAN style="COLOR: #2b91af">CommandWithResultExpression
</SPAN>{
    <SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">Expression </SPAN>Check { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">InsertExpression </SPAN>Insert { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">UpdateExpression </SPAN>Update { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: blue">public override </SPAN><SPAN style="COLOR: #2b91af">Expression </SPAN>Result { <SPAN style="COLOR: blue">get</SPAN>; }
}

<SPAN style="COLOR: blue">public class </SPAN><SPAN style="COLOR: #2b91af">DeleteExpression </SPAN>: <SPAN style="COLOR: #2b91af">CommandExpression
</SPAN>{
    <SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">TableExpression </SPAN>Table { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">Expression </SPAN>Where { <SPAN style="COLOR: blue">get</SPAN>; }
}

<SPAN style="COLOR: blue">public class </SPAN><SPAN style="COLOR: #2b91af">BatchExpression </SPAN>: <SPAN style="COLOR: #2b91af">CommandExpression
</SPAN>{
    <SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">Expression </SPAN>Input { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">LambdaExpression </SPAN>Operation { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">Expression </SPAN>BatchSize { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">Expression </SPAN>Stream { <SPAN style="COLOR: blue">get</SPAN>; }
}</PRE>
<P>Then there's the standard visit method in DbExpressionVisitor, DbExpressionWriter, etc.&nbsp; Binding them happens in the QueryBinder just like all other query operations, but the work of deciding what nodes to generate gets doled out to the QueryMapping object.&nbsp; Luckily, the base QueryMapping class has a default implementation that builds the correct DbExpression node.&nbsp; If you want to map a single object into multiple tables or some other crazy scheme you'll probably have to have a more advanced mapping implementation. :-)</P>
<P>These nodes get plumbed through the system until they are encountered by the ExecutionBuilder and are formatted using the QueryLanguage rules. The TSQL formatter converts the nodes into corresponding TSQL text.&nbsp; Depending on the contents of the command expression, the generated SQL may have one or more actual TSQL operations.</P>
<H2>Batch Processing</H2>
<P>ADO.Net has this nice feature built into its SqlClient API; the ability to get high-performance batch processing. Yet, the only way to get at it is through use of DataSet's or DataReaders. As far as I'm concerned this is rather low level and a bit complicated to use if you are starting out with domain objects and not DataSets. Your data access layer should do this for you. Yet, in order for it to do it, the abstraction for batch processing has to exist, which is why I added it to the updatable pattern.&nbsp; After that it was a cinch. :-)&nbsp; Not really.&nbsp; </P>
<P>What I needed fundamentally was something that would execute the same database command over and over again with different sets of parameters. This is basically what TSQL batching does as it is sent over the wire. So I needed to add this abstraction to DbQueryProvider. Yet, since only SqlClient supports this actually behavior I'd need a fall back plan. So DbQueryProvider implements a method to do batch processing, but it does not actually do it optimally.&nbsp; </P><PRE class=code><SPAN style="COLOR: blue">public virtual </SPAN><SPAN style="COLOR: #2b91af">IEnumerable</SPAN>&lt;<SPAN style="COLOR: blue">int</SPAN>&gt; ExecuteBatch(<SPAN style="COLOR: #2b91af">QueryCommand </SPAN>query, <SPAN style="COLOR: #2b91af">IEnumerable</SPAN>&lt;<SPAN style="COLOR: blue">object</SPAN>[]&gt; paramSets, <SPAN style="COLOR: blue">int </SPAN>batchSize, <SPAN style="COLOR: blue">bool </SPAN>stream)
{
    <SPAN style="COLOR: blue">var </SPAN>result = <SPAN style="COLOR: blue">this</SPAN>.ExecuteBatch(query, paramSets);
    <SPAN style="COLOR: blue">if </SPAN>(!stream)
    {
        <SPAN style="COLOR: blue">return </SPAN>result.ToList();
    }
    <SPAN style="COLOR: blue">else
    </SPAN>{
        <SPAN style="COLOR: blue">return new </SPAN><SPAN style="COLOR: #2b91af">EnumerateOnce</SPAN>&lt;<SPAN style="COLOR: blue">int</SPAN>&gt;(result);
    }
}

<SPAN style="COLOR: blue">private </SPAN><SPAN style="COLOR: #2b91af">IEnumerable</SPAN>&lt;<SPAN style="COLOR: blue">int</SPAN>&gt; ExecuteBatch(<SPAN style="COLOR: #2b91af">QueryCommand </SPAN>query, <SPAN style="COLOR: #2b91af">IEnumerable</SPAN>&lt;<SPAN style="COLOR: blue">object</SPAN>[]&gt; paramSets)
{
    <SPAN style="COLOR: blue">this</SPAN>.LogCommand(query, <SPAN style="COLOR: blue">null</SPAN>);
    <SPAN style="COLOR: #2b91af">DbCommand </SPAN>cmd = <SPAN style="COLOR: blue">this</SPAN>.GetCommand(query, <SPAN style="COLOR: blue">null</SPAN>);
    <SPAN style="COLOR: blue">foreach </SPAN>(<SPAN style="COLOR: blue">var </SPAN>paramValues <SPAN style="COLOR: blue">in </SPAN>paramSets)
    {
        <SPAN style="COLOR: blue">this</SPAN>.LogMessage(<SPAN style="COLOR: #a31515">""</SPAN>);
        <SPAN style="COLOR: blue">this</SPAN>.LogParameters(query, paramValues);
        <SPAN style="COLOR: blue">this</SPAN>.SetParameterValues(cmd, paramValues);
        <SPAN style="COLOR: blue">int </SPAN>result = cmd.ExecuteNonQuery();
        <SPAN style="COLOR: blue">yield return </SPAN>result;
    }
}

<SPAN style="COLOR: blue">public virtual </SPAN><SPAN style="COLOR: #2b91af">IEnumerable</SPAN>&lt;T&gt; ExecuteBatch&lt;T&gt;(<SPAN style="COLOR: #2b91af">QueryCommand </SPAN>query, <SPAN style="COLOR: #2b91af">IEnumerable</SPAN>&lt;<SPAN style="COLOR: blue">object</SPAN>[]&gt; paramSets, <SPAN style="COLOR: #2b91af">Func</SPAN>&lt;<SPAN style="COLOR: #2b91af">DbDataReader</SPAN>, T&gt; fnProjector, <SPAN style="COLOR: blue">int </SPAN>batchSize, <SPAN style="COLOR: blue">bool </SPAN>stream)
{
    <SPAN style="COLOR: blue">var </SPAN>result = <SPAN style="COLOR: blue">this</SPAN>.ExecuteBatch(query, paramSets, fnProjector);
    <SPAN style="COLOR: blue">if </SPAN>(!stream)
    {
        <SPAN style="COLOR: blue">return </SPAN>result.ToList();
    }
    <SPAN style="COLOR: blue">else
    </SPAN>{
        <SPAN style="COLOR: blue">return new </SPAN><SPAN style="COLOR: #2b91af">EnumerateOnce</SPAN>&lt;T&gt;(result);
    }
}

<SPAN style="COLOR: blue">private </SPAN><SPAN style="COLOR: #2b91af">IEnumerable</SPAN>&lt;T&gt; ExecuteBatch&lt;T&gt;(<SPAN style="COLOR: #2b91af">QueryCommand </SPAN>query, <SPAN style="COLOR: #2b91af">IEnumerable</SPAN>&lt;<SPAN style="COLOR: blue">object</SPAN>[]&gt; paramSets, <SPAN style="COLOR: #2b91af">Func</SPAN>&lt;<SPAN style="COLOR: #2b91af">DbDataReader</SPAN>, T&gt; fnProjector)
{
    <SPAN style="COLOR: blue">this</SPAN>.LogCommand(query, <SPAN style="COLOR: blue">null</SPAN>);
    <SPAN style="COLOR: #2b91af">DbCommand </SPAN>cmd = <SPAN style="COLOR: blue">this</SPAN>.GetCommand(query, <SPAN style="COLOR: blue">null</SPAN>);
    cmd.Prepare();
    <SPAN style="COLOR: blue">foreach </SPAN>(<SPAN style="COLOR: blue">var </SPAN>paramValues <SPAN style="COLOR: blue">in </SPAN>paramSets)
    {
        <SPAN style="COLOR: blue">this</SPAN>.LogMessage(<SPAN style="COLOR: #a31515">""</SPAN>);
        <SPAN style="COLOR: blue">this</SPAN>.LogParameters(query, paramValues);
        <SPAN style="COLOR: blue">this</SPAN>.SetParameterValues(cmd, paramValues);
        <SPAN style="COLOR: blue">var </SPAN>reader = cmd.ExecuteReader();
        <SPAN style="COLOR: blue">if </SPAN>(reader.HasRows)
        {
            reader.Read();
            <SPAN style="COLOR: blue">yield return </SPAN>fnProjector(reader);
        }
        <SPAN style="COLOR: blue">else
        </SPAN>{
            <SPAN style="COLOR: blue">yield return default</SPAN>(T);
        }
        reader.Close();
    }
}</PRE><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A>
<P>What I have here are four methods, two of which are just private implementations, but two others that are virtual so can be overridden. Batching can work via streaming or not. If streamed the results of each execution (or batch) is yielded out. This works great if the number of individual items is large, but takes a lot of discipline to remember to actually inspect the results or nothing gets executed at all!&nbsp; By requesting no streaming (stream == false) the execution occurs immediately and the results are packaged into a list that you can conveniently ignore if you so choose. That's why the implementation is separated out, so that the enumerable can be captured and converted to a list, enabling either behavior.&nbsp; The two types of ExecuteBatch differ in whether a result is computed via information coming back from the server or not.</P>
<P>Now that these are defined, I can implement a new kind of provider, a SqlClient specific version that makes automatic use of optimized batching.</P><PRE class=code><SPAN style="COLOR: blue">public class </SPAN><SPAN style="COLOR: #2b91af">SqlQueryProvider </SPAN>: <SPAN style="COLOR: #2b91af">DbQueryProvider
</SPAN>{
    ...<BR>
    <SPAN style="COLOR: blue">public override </SPAN><SPAN style="COLOR: #2b91af">IEnumerable</SPAN>&lt;<SPAN style="COLOR: blue">int</SPAN>&gt; ExecuteBatch(<SPAN style="COLOR: #2b91af">QueryCommand </SPAN>query, <SPAN style="COLOR: #2b91af">IEnumerable</SPAN>&lt;<SPAN style="COLOR: blue">object</SPAN>[]&gt; paramSets, <SPAN style="COLOR: blue">int </SPAN>batchSize, <SPAN style="COLOR: blue">bool </SPAN>stream)
    {
        <SPAN style="COLOR: blue">var </SPAN>result = <SPAN style="COLOR: blue">this</SPAN>.ExecuteBatch(query, paramSets, batchSize);
        <SPAN style="COLOR: blue">if </SPAN>(!stream)
        {
            <SPAN style="COLOR: blue">return </SPAN>result.ToList();
        }
        <SPAN style="COLOR: blue">else
        </SPAN>{
            <SPAN style="COLOR: blue">return new </SPAN><SPAN style="COLOR: #2b91af">EnumerateOnce</SPAN>&lt;<SPAN style="COLOR: blue">int</SPAN>&gt;(result);
        }
    }

    <SPAN style="COLOR: blue">private </SPAN><SPAN style="COLOR: #2b91af">IEnumerable</SPAN>&lt;<SPAN style="COLOR: blue">int</SPAN>&gt; ExecuteBatch(<SPAN style="COLOR: #2b91af">QueryCommand </SPAN>query, <SPAN style="COLOR: #2b91af">IEnumerable</SPAN>&lt;<SPAN style="COLOR: blue">object</SPAN>[]&gt; paramSets, <SPAN style="COLOR: blue">int </SPAN>batchSize)
    {
        <SPAN style="COLOR: #2b91af">SqlCommand </SPAN>cmd = (<SPAN style="COLOR: #2b91af">SqlCommand</SPAN>)<SPAN style="COLOR: blue">this</SPAN>.GetCommand(query, <SPAN style="COLOR: blue">null</SPAN>);
        <SPAN style="COLOR: #2b91af">DataTable </SPAN>dataTable = <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">DataTable</SPAN>();
        <SPAN style="COLOR: blue">for </SPAN>(<SPAN style="COLOR: blue">int </SPAN>i = 0, n = query.Parameters.Count; i &lt; n; i++)
        {
            <SPAN style="COLOR: blue">var </SPAN>qp = query.Parameters[i];
            cmd.Parameters[i].SourceColumn = qp.Name;
            dataTable.Columns.Add(qp.Name, qp.Type);
        }
        <SPAN style="COLOR: #2b91af">SqlDataAdapter </SPAN>dataAdapter = <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">SqlDataAdapter</SPAN>();
        dataAdapter.InsertCommand = cmd;
        dataAdapter.InsertCommand.UpdatedRowSource = <SPAN style="COLOR: #2b91af">UpdateRowSource</SPAN>.None;
        dataAdapter.UpdateBatchSize = batchSize;

        <SPAN style="COLOR: blue">this</SPAN>.LogMessage(<SPAN style="COLOR: #a31515">"-- Start SQL Batching --"</SPAN>);
        <SPAN style="COLOR: blue">this</SPAN>.LogCommand(query, <SPAN style="COLOR: blue">null</SPAN>);

        <SPAN style="COLOR: #2b91af">IEnumerator</SPAN>&lt;<SPAN style="COLOR: blue">object</SPAN>[]&gt; en = paramSets.GetEnumerator();
        <SPAN style="COLOR: blue">using </SPAN>(en)
        {
            <SPAN style="COLOR: blue">bool </SPAN>hasNext = <SPAN style="COLOR: blue">true</SPAN>;
            <SPAN style="COLOR: blue">while </SPAN>(hasNext)
            {
                <SPAN style="COLOR: blue">int </SPAN>count = 0;
                <SPAN style="COLOR: blue">for </SPAN>(; count &lt; dataAdapter.UpdateBatchSize &amp;&amp; (hasNext = en.MoveNext()); count++)
                {
                    <SPAN style="COLOR: blue">var </SPAN>paramValues = en.Current;
                    dataTable.Rows.Add(paramValues);
                    <SPAN style="COLOR: blue">this</SPAN>.LogMessage(<SPAN style="COLOR: #a31515">""</SPAN>);
                    <SPAN style="COLOR: blue">this</SPAN>.LogParameters(query, paramValues);
                }
                <SPAN style="COLOR: blue">if </SPAN>(count &gt; 0)
                {
                    <SPAN style="COLOR: blue">int </SPAN>n = dataAdapter.Update(dataTable);
                    <SPAN style="COLOR: blue">for </SPAN>(<SPAN style="COLOR: blue">int </SPAN>i = 0; i &lt; count; i++)
                    {
                        <SPAN style="COLOR: blue">yield return </SPAN>(i &lt; n) ? 1 : 0;
                    }
                    dataTable.Rows.Clear();
                }
            }
        }

        <SPAN style="COLOR: blue">this</SPAN>.LogMessage(<SPAN style="COLOR: blue">string</SPAN>.Format(<SPAN style="COLOR: #a31515">"-- End SQL Batching --"</SPAN>));
    }
}</PRE>
<P>Note that I only have an implementation for the variation of ExecuteBatch that computes no user specified result. This is due to there being no back-channel available when using SqlClient batching. </P>
<P>The implementation uses DataTable's and DataAdapters to make this work.&nbsp; A DataTable is created filled with the parameters necessary for executing the command.&nbsp; The DataAdapter is used to invoke the batch using the Update method.&nbsp; Of course, this doesn't actually have to be an update command. I can also use this to batch inserts and deletes too, or really any TSQL that I want to execute as long as I don't expected to get a bunch of data back.</P>
<H2>Server Language Types</H2>
<P>One thing that has always bugged me about SQL Server was the need to get the command parameters right. If I declare the parameter to be the wrong text flavor I can cause serious performance issues for the query. So just setting the parameter values and having the SqlCommand object guess at the right SqlType encoding is really not a good plan. Fortunately, it is often possible to figure out the correct parameter types to use if the information is available via the mapping. Parameters are often never just sent to the server for no reason. If I use a parameter in a query I'm usually comparing it against a column.&nbsp; In most cases I can simply infer that the parameter should have the same server type as the column.</P>
<P>So I've gone ahead and defined a new server type system abstraction and threaded it into some of the DbExpressions and make use of it in some of the visitors.&nbsp; </P><PRE class=code><SPAN style="COLOR: blue">public abstract class </SPAN><SPAN style="COLOR: #2b91af">QueryType
</SPAN>{
    <SPAN style="COLOR: blue">public abstract </SPAN><SPAN style="COLOR: #2b91af">DbType </SPAN>DbType { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: blue">public abstract bool </SPAN>NotNull { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: blue">public abstract int </SPAN>Length { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: blue">public abstract short </SPAN>Precision { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: blue">public abstract short </SPAN>Scale { <SPAN style="COLOR: blue">get</SPAN>; }
}

<SPAN style="COLOR: blue">public abstract class </SPAN><SPAN style="COLOR: #2b91af">QueryTypeSystem 
</SPAN>{
    <SPAN style="COLOR: blue">public abstract </SPAN><SPAN style="COLOR: #2b91af">QueryType </SPAN>Parse(<SPAN style="COLOR: blue">string </SPAN>typeDeclaration);
    <SPAN style="COLOR: blue">public abstract </SPAN><SPAN style="COLOR: #2b91af">QueryType </SPAN>GetColumnType(<SPAN style="COLOR: #2b91af">Type </SPAN>type);        
}</PRE>
<P>A QueryType encodes the typical database scalar type. It has a few properties that you can use to inspect common attributes of a server type, but most code won't really care to know the details, it will just pass the information along until it ends up where I need it.&nbsp; A QueryTypeSystem is basically a factory for producing QueryType's.&nbsp; The Parse method will construct a language-specific QueryType out of some text encoding.&nbsp; This is typically the server language syntax for declaring a column of that particular type, like 'VARCHAR(10)'.&nbsp; </P>
<P>A QueryTypeSystem is specific to a language, so QueryLanguage is where you go to get one.</P><PRE class=code><SPAN style="COLOR: blue">public abstract class </SPAN><SPAN style="COLOR: #2b91af">QueryLanguage
</SPAN>{
    <SPAN style="COLOR: blue">public abstract </SPAN><SPAN style="COLOR: #2b91af">QueryTypeSystem </SPAN>TypeSystem { <SPAN style="COLOR: blue">get</SPAN>; }<BR>}</PRE><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A>
<P>One place I definitely know where to encode server types is in the ColumnExpression.&nbsp; If a ColumnExpression knows what its server type is, then when I get to the point of comparing parameters to columns I know which server type is in play.</P><PRE class=code><SPAN style="COLOR: blue">public class </SPAN><SPAN style="COLOR: #2b91af">ColumnExpression </SPAN>: <SPAN style="COLOR: #2b91af">DbExpression</SPAN>, <SPAN style="COLOR: #2b91af">IEquatable</SPAN>&lt;<SPAN style="COLOR: #2b91af">ColumnExpression</SPAN>&gt;
{
    <SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">QueryType </SPAN>QueryType { <SPAN style="COLOR: blue">get</SPAN>; }
}</PRE><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A>
<P>I've also stuck it into NamedValueExpression, because that's the type I'm using for parameters. </P><PRE class=code><SPAN style="COLOR: blue">public class </SPAN><SPAN style="COLOR: #2b91af">NamedValueExpression </SPAN>: <SPAN style="COLOR: #2b91af">DbExpression
</SPAN>{
    <SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">QueryType </SPAN>QueryType { <SPAN style="COLOR: blue">get</SPAN>; }<BR>}</PRE><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A>
<P>And I've basically modified Parameterizer, so that if a column and parameter (named-value expression) are ever paired together in any binary expression, I'll infer the parameter to have the same server type as the column.</P><PRE class=code><SPAN style="COLOR: blue">public class </SPAN><SPAN style="COLOR: #2b91af">Parameterizer </SPAN>: <SPAN style="COLOR: #2b91af">DbExpressionVisitor
</SPAN>{
    <SPAN style="COLOR: blue">protected override </SPAN><SPAN style="COLOR: #2b91af">Expression </SPAN>VisitBinary(<SPAN style="COLOR: #2b91af">BinaryExpression </SPAN>b)
    {
        <SPAN style="COLOR: #2b91af">Expression </SPAN>left = <SPAN style="COLOR: blue">this</SPAN>.Visit(b.Left);
        <SPAN style="COLOR: #2b91af">Expression </SPAN>right = <SPAN style="COLOR: blue">this</SPAN>.Visit(b.Right);
        <SPAN style="COLOR: blue">if </SPAN>(left.NodeType == (<SPAN style="COLOR: #2b91af">ExpressionType</SPAN>)<SPAN style="COLOR: #2b91af">DbExpressionType</SPAN>.NamedValue
         &amp;&amp; right.NodeType == (<SPAN style="COLOR: #2b91af">ExpressionType</SPAN>)<SPAN style="COLOR: #2b91af">DbExpressionType</SPAN>.Column)
        {
            <SPAN style="COLOR: #2b91af">NamedValueExpression </SPAN>nv = (<SPAN style="COLOR: #2b91af">NamedValueExpression</SPAN>)left;
            <SPAN style="COLOR: #2b91af">ColumnExpression </SPAN>c = (<SPAN style="COLOR: #2b91af">ColumnExpression</SPAN>)right;
            left = <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">NamedValueExpression</SPAN>(nv.Name, c.QueryType, nv.Value);
        }
        <SPAN style="COLOR: blue">else if </SPAN>(b.Right.NodeType == (<SPAN style="COLOR: #2b91af">ExpressionType</SPAN>)<SPAN style="COLOR: #2b91af">DbExpressionType</SPAN>.NamedValue
         &amp;&amp; b.Left.NodeType == (<SPAN style="COLOR: #2b91af">ExpressionType</SPAN>)<SPAN style="COLOR: #2b91af">DbExpressionType</SPAN>.Column)
        {
            <SPAN style="COLOR: #2b91af">NamedValueExpression </SPAN>nv = (<SPAN style="COLOR: #2b91af">NamedValueExpression</SPAN>)right;
            <SPAN style="COLOR: #2b91af">ColumnExpression </SPAN>c = (<SPAN style="COLOR: #2b91af">ColumnExpression</SPAN>)left;
            right = <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">NamedValueExpression</SPAN>(nv.Name, c.QueryType, nv.Value);
        }
        <SPAN style="COLOR: blue">return this</SPAN>.UpdateBinary(b, left, right, b.Conversion, b.IsLiftedToNull, b.Method);
    }

    <SPAN style="COLOR: blue">protected override </SPAN><SPAN style="COLOR: #2b91af">ColumnAssignment </SPAN>VisitColumnAssignment(<SPAN style="COLOR: #2b91af">ColumnAssignment </SPAN>ca)
    {
        ca = <SPAN style="COLOR: blue">base</SPAN>.VisitColumnAssignment(ca);
        <SPAN style="COLOR: #2b91af">Expression </SPAN>expression = ca.Expression;
        <SPAN style="COLOR: #2b91af">NamedValueExpression </SPAN>nv = expression <SPAN style="COLOR: blue">as </SPAN><SPAN style="COLOR: #2b91af">NamedValueExpression</SPAN>;
        <SPAN style="COLOR: blue">if </SPAN>(nv != <SPAN style="COLOR: blue">null</SPAN>)
        {
            expression = <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">NamedValueExpression</SPAN>(nv.Name, ca.Column.QueryType, nv.Value);
        }
        <SPAN style="COLOR: blue">return this</SPAN>.UpdateColumnAssignment(ca, ca.Column, expression);
    }<BR>}</PRE><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A>
<P>Of course, the same goes for ColumnAssignment used by Insert and Update commands. You'll notice that I'm not having these types flow throughout the expression tree like normal types.&nbsp; I could probably get more edge cases correct if I did, but for now this handles most of the cases.&nbsp; </P>
<P>The GetCommand method in&nbsp; DbQueryProvider will now make use of this info when constructing parameters. The SqlQueryProvider expects to see a new TSqlType that's made available by a new TSqlTypeSystem found on the TSqlLanguage object.&nbsp; :-)</P><PRE class=code><SPAN style="COLOR: blue">public class </SPAN><SPAN style="COLOR: #2b91af">SqlQueryProvider </SPAN>: <SPAN style="COLOR: #2b91af">DbQueryProvider
</SPAN>{
    <SPAN style="COLOR: blue">protected override </SPAN><SPAN style="COLOR: #2b91af">DbCommand </SPAN>GetCommand(<SPAN style="COLOR: #2b91af">QueryCommand </SPAN>query, <SPAN style="COLOR: blue">object</SPAN>[] paramValues)
    {
        <SPAN style="COLOR: green">// create command object (and fill in parameters)
        </SPAN><SPAN style="COLOR: #2b91af">SqlCommand </SPAN>cmd = <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">SqlCommand</SPAN>(query.CommandText, (<SPAN style="COLOR: #2b91af">SqlConnection</SPAN>)<SPAN style="COLOR: blue">this</SPAN>.Connection);
        <SPAN style="COLOR: blue">for </SPAN>(<SPAN style="COLOR: blue">int </SPAN>i = 0, n = query.Parameters.Count; i &lt; n; i++)
        {
            <SPAN style="COLOR: #2b91af">QueryParameter </SPAN>qp = query.Parameters[i];
            <SPAN style="COLOR: #2b91af">TSqlType </SPAN>sqlType = (<SPAN style="COLOR: #2b91af">TSqlType</SPAN>)qp.QueryType;
            <SPAN style="COLOR: blue">if </SPAN>(sqlType == <SPAN style="COLOR: blue">null</SPAN>)
                sqlType = (<SPAN style="COLOR: #2b91af">TSqlType</SPAN>)<SPAN style="COLOR: blue">this</SPAN>.Language.TypeSystem.GetColumnType(qp.Type);
            <SPAN style="COLOR: blue">var </SPAN>p = cmd.Parameters.Add(<SPAN style="COLOR: #a31515">"@" </SPAN>+ qp.Name, sqlType.SqlDbType, sqlType.Length);
            <SPAN style="COLOR: blue">if </SPAN>(sqlType.Precision != 0)
                p.Precision = (<SPAN style="COLOR: blue">byte</SPAN>)sqlType.Precision;
            <SPAN style="COLOR: blue">if </SPAN>(sqlType.Scale != 0)
                p.Scale = (<SPAN style="COLOR: blue">byte</SPAN>)sqlType.Scale;
            <SPAN style="COLOR: blue">if </SPAN>(paramValues != <SPAN style="COLOR: blue">null</SPAN>)
            {
                p.Value = paramValues[i] ?? <SPAN style="COLOR: #2b91af">DBNull</SPAN>.Value;
            }
        }
        <SPAN style="COLOR: blue">return </SPAN>cmd;
    }<BR>}</PRE><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A>
<H2>Mapping Changes</H2>
<P>I've made some changes to the mapping system (or QueryMapping to be particular.)&nbsp; I came across a variety of odd behavior while developing update logic that basically boiled down to the ImplictMapping object not being able to tell the difference between a type that was intended to correspond to a database table and others that appeared there just for the sake of representation, like LINQ anonymous types.&nbsp; Some other mapping implementations might be able to tell the difference, but the simplest one couldn't so I needed to find another solution. </P>
<P>Obviously, everything that is an entity in a query comes from somewhere, and that's either from one of the roots of the query (a table) or via a relationship property. It was a mistake to think otherwise (or not think about it at all.) What I needed was a more explicit representation in the expression tree of what was an entity and what was not.&nbsp; I figured I could either add annotations to the tree in every node, or find some nominal solution that would do the trick.&nbsp; </P>
<P>I chose to make a new expression node, EntityExpression, which I use as a wrapper around any expression that would be normally constructing an entitiy.&nbsp; This node is placed into the system when the QueryMapping first creates the sub-express for constructing an entity or relationship, at the time I actually know that I'm dealing with an entity and in particular which entity it is. </P><PRE class=code><SPAN style="COLOR: blue">public class </SPAN><SPAN style="COLOR: #2b91af">EntityExpression </SPAN>: <SPAN style="COLOR: #2b91af">DbExpression
</SPAN>{
    <SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">MappingEntity </SPAN>Entity { <SPAN style="COLOR: blue">get </SPAN>; }
    <SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">Expression </SPAN>Expression { <SPAN style="COLOR: blue">get</SPAN>; }
}</PRE><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A>
<P>I've also introduced a new abstraction called MappingEntity.&nbsp; This how I let the QueryMapping object place a bread-crumb into the expression tree so it can be reminded which exact entity was being referred to.</P><PRE class=code><SPAN style="COLOR: blue">public class </SPAN><SPAN style="COLOR: #2b91af">MappingEntity
</SPAN>{
    <SPAN style="COLOR: blue">public string </SPAN>TableID { <SPAN style="COLOR: blue">get</SPAN>; }
    <SPAN style="COLOR: blue">public </SPAN><SPAN style="COLOR: #2b91af">Type </SPAN>Type { <SPAN style="COLOR: blue">get</SPAN>; }
}</PRE><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A>
<P>It' really just as simple little class that minimally remembers the correspondence between the runtime type and the table its being mapped to.&nbsp; If you've been paying attention you'll realize that this 'TableID' is the same property that was added to the IQueryableTable interface.&nbsp; That's how the query engine gets the table-id in the first place, right from the start of the query.&nbsp; Of course, the IQueryableTable&lt;T&gt; interface also knows the runtime type, that's the 'T' part.&nbsp; So your table's have all the information needed to make a MappingEntity.&nbsp; Except that job is deferred to the QueryMapping object so it can do whatever bookkeeping it wants.</P><PRE class=code><SPAN style="COLOR: blue">public abstract class </SPAN><SPAN style="COLOR: #2b91af">QueryMapping
</SPAN>{<BR><SPAN style="COLOR: blue">    public virtual </SPAN><SPAN style="COLOR: #2b91af">MappingEntity </SPAN>GetEntity(<SPAN style="COLOR: #2b91af">Type </SPAN>type);
<SPAN style="COLOR: blue">    public virtual </SPAN><SPAN style="COLOR: #2b91af">MappingEntity </SPAN>GetEntity(<SPAN style="COLOR: #2b91af">Type </SPAN>type, <SPAN style="COLOR: blue">string </SPAN>tableID);
}</PRE>
<P>You'll also notice that most of the other methods on QueryMapping are now modified to take a MappingEntity as an argument.</P><PRE class=code><SPAN style="COLOR: blue">public abstract class </SPAN><SPAN style="COLOR: #2b91af">QueryMapping
</SPAN>{
<SPAN style="COLOR: blue">    public virtual bool </SPAN>IsMapped(<SPAN style="COLOR: #2b91af">MappingEntity </SPAN>entity, <SPAN style="COLOR: #2b91af">MemberInfo </SPAN>member)
<SPAN style="COLOR: blue">    public virtual bool </SPAN>IsColumn(<SPAN style="COLOR: #2b91af">MappingEntity </SPAN>entity, <SPAN style="COLOR: #2b91af">MemberInfo </SPAN>member)
<SPAN style="COLOR: blue">    public virtual bool </SPAN>IsIdentity(<SPAN style="COLOR: #2b91af">MappingEntity </SPAN>entity, <SPAN style="COLOR: #2b91af">MemberInfo </SPAN>member)
<SPAN style="COLOR: blue">    public virtual bool </SPAN>IsComputed(<SPAN style="COLOR: #2b91af">MappingEntity </SPAN>entity, <SPAN style="COLOR: #2b91af">MemberInfo </SPAN>member)
<SPAN style="COLOR: blue">    public virtual bool </SPAN>IsGenerated(<SPAN style="COLOR: #2b91af">MappingEntity </SPAN>entity, <SPAN style="COLOR: #2b91af">MemberInfo </SPAN>member)
<SPAN style="COLOR: blue">    public virtual bool </SPAN>IsRelationship(<SPAN style="COLOR: #2b91af">MappingEntity </SPAN>entity, <SPAN style="COLOR: #2b91af">MemberInfo </SPAN>member)
<SPAN style="COLOR: blue">    public virtual </SPAN><SPAN style="COLOR: #2b91af">MappingEntity </SPAN>GetRelatedEntity(<SPAN style="COLOR: #2b91af">MappingEntity </SPAN>entity, <SPAN style="COLOR: #2b91af">MemberInfo </SPAN>member)
<SPAN style="COLOR: blue">    public virtual bool </SPAN>IsAssociationRelationship(<SPAN style="COLOR: #2b91af">MappingEntity </SPAN>entity, <SPAN style="COLOR: #2b91af">MemberInfo </SPAN>member)<BR>    ...
}</PRE><A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"></A>
<P>Now, what you're probably saying is "Gee, Matt, that's looks a bit ominous. Why aren't these all just methods on MappingEntity now?"&nbsp; And you'd be right. They probably should be.&nbsp; Yet, it makes it a lot more difficult to subclass the mapping object and merely override some of the behavior.&nbsp; Not a big deal for complete mapping sub-systems that someday might exists, but painful for simple uses such as overriding the ImplicitMapping with a few additional rules.&nbsp; So I'm leaving it as-is for now until I can think about it more.&nbsp; Any thoughts from the peanut-gallery?</P>
<P>Also, its worth nothing, that given this new arrangement, with explicit entity information in the query tree and connecting each entity info back to the table it originated from, it is now possible to support mapping systems that allow individual runtime types to be mapped to more than one table.&nbsp; So you can have your cake and eat it too!&nbsp; </P>
<H3>That's All Folks!</H3>
<P>At least for today.&nbsp; The future may hold more goodies.&nbsp; Any suggestions are welcome, either as ideas or source-code contributions.</P>
<P>Remember, you can get the current sources at CodePlex:&nbsp; <A href="http://www.codeplex.com/IQToolkit" mce_href="http://www.codeplex.com/IQToolkit">http://www.codeplex.com/IQToolkit</A></P>]]></content:encoded>
    </item>
    <item>
      <title>LINQ IQToolkit on CodePlex</title>
      <link>https://docs.microsoft.com/archive/blogs/mattwar/linq-iqtoolkit-on-codeplex</link>
      <pubDate>Fri, 21 Nov 2008 16:14:00 GMT</pubDate>
      <dc:creator><![CDATA[Matt Warren - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mattwar/2008/11/21/linq-iqtoolkit-on-codeplex/</guid>
      <description><![CDATA[The LINQ IQueryable Toolkit is now a CodePlex project.&nbsp;...]]></description>
      <content:encoded><![CDATA[<P>The LINQ IQueryable Toolkit is now a CodePlex project.&nbsp; </P>
<P><A href="http://www.codeplex.com/IQToolkit">http://www.codeplex.com/IQToolkit</A>&nbsp; </P>
<P>Going forward this will the be official site to find the latest greatest source bits.&nbsp; I'll&nbsp;continue to post here about the toolkit, how to use it and to show off new features in this blog, but you'll have to follow a link to download.</P>
<P>You can also start discussions over how utterly fabulous the source code is and how you can't wait for the next drop.&nbsp; </P>
<P>It's up to you.</P>]]></content:encoded>
    </item>
    <item>
      <title>LINQ: Building an IQueryable provider series</title>
      <link>https://docs.microsoft.com/archive/blogs/mattwar/linq-building-an-iqueryable-provider-series</link>
      <pubDate>Tue, 18 Nov 2008 09:18:00 GMT</pubDate>
      <dc:creator><![CDATA[Matt Warren - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mattwar/2008/11/18/linq-building-an-iqueryable-provider-series/</guid>
      <description><![CDATA[Here's a list of all the posts in the building an IQueryable provider series.&nbsp; If you want to...]]></description>
      <content:encoded><![CDATA[<P>Here's a list of all the posts in the building an IQueryable provider series.&nbsp; If you want to get the latest and greatest source code just follow that last link.&nbsp; If you want to discover how to build your own IQueryable provider read from the beginning.&nbsp; It is sort of like a tutorial.</P>
<P><A href="http://blogs.msdn.com/mattwar/archive/2007/07/30/linq-building-an-iqueryable-provider-part-i.aspx" mce_href="http://blogs.msdn.com/mattwar/archive/2007/07/30/linq-building-an-iqueryable-provider-part-i.aspx"><FONT color=#0000cc>Part I - Reusable IQueryable base classes</FONT></A> <BR><A href="http://blogs.msdn.com/mattwar/archive/2007/07/31/linq-building-an-iqueryable-provider-part-ii.aspx" mce_href="http://blogs.msdn.com/mattwar/archive/2007/07/31/linq-building-an-iqueryable-provider-part-ii.aspx"><FONT color=#0000cc>Part II - Where and reusable Expression tree visitor</FONT></A> <BR><A href="http://blogs.msdn.com/mattwar/archive/2007/08/01/linq-building-an-iqueryable-provider-part-iii.aspx" mce_href="http://blogs.msdn.com/mattwar/archive/2007/08/01/linq-building-an-iqueryable-provider-part-iii.aspx"><FONT color=#0000cc>Part II - Local variable references</FONT></A> <BR><A href="http://blogs.msdn.com/mattwar/archive/2007/08/02/linq-building-an-iqueryable-provider-part-iv.aspx" mce_href="http://blogs.msdn.com/mattwar/archive/2007/08/02/linq-building-an-iqueryable-provider-part-iv.aspx"><FONT color=#0000cc>Part IV - Select</FONT></A> <BR><A href="http://blogs.msdn.com/mattwar/archive/2007/08/03/linq-building-an-iqueryable-provider-part-v.aspx" mce_href="http://blogs.msdn.com/mattwar/archive/2007/08/03/linq-building-an-iqueryable-provider-part-v.aspx"><FONT color=#0000cc>Part V - Improved Column binding</FONT></A> <BR><A href="http://blogs.msdn.com/mattwar/archive/2007/08/09/linq-building-an-iqueryable-provider-part-vi.aspx" mce_href="http://blogs.msdn.com/mattwar/archive/2007/08/09/linq-building-an-iqueryable-provider-part-vi.aspx"><FONT color=#0000cc>Part VI - Nested queries</FONT></A> <BR><A href="http://blogs.msdn.com/mattwar/archive/2007/09/04/linq-building-an-iqueryable-provider-part-vii.aspx" mce_href="http://blogs.msdn.com/mattwar/archive/2007/09/04/linq-building-an-iqueryable-provider-part-vii.aspx"><FONT color=#0000cc>Part VII - Join and SelectMany</FONT></A> <BR><A href="http://blogs.msdn.com/mattwar/archive/2007/10/09/linq-building-an-iqueryable-provider-part-viii.aspx" mce_href="http://blogs.msdn.com/mattwar/archive/2007/10/09/linq-building-an-iqueryable-provider-part-viii.aspx"><FONT color=#0000cc>Part VIII - OrderBy</FONT></A> <BR><A href="http://blogs.msdn.com/mattwar/archive/2008/01/16/linq-building-an-iqueryable-provider-part-ix.aspx" mce_href="http://blogs.msdn.com/mattwar/archive/2008/01/16/linq-building-an-iqueryable-provider-part-ix.aspx"><FONT color=#0000cc>Part IX - Removing redundant subqueries</FONT></A> <BR><A href="http://blogs.msdn.com/mattwar/archive/2008/07/08/linq-building-an-iqueryable-provider-part-x.aspx" mce_href="http://blogs.msdn.com/mattwar/archive/2008/07/08/linq-building-an-iqueryable-provider-part-x.aspx"><FONT color=#0000cc>Part X – GroupBy and Aggregates</FONT></A> <BR><A href="http://blogs.msdn.com/mattwar/archive/2008/07/14/linq-building-an-iqueryable-provider-part-xi.aspx" mce_href="http://blogs.msdn.com/mattwar/archive/2008/07/14/linq-building-an-iqueryable-provider-part-xi.aspx"><FONT color=#0000cc>Part XI - More of everything</FONT></A><BR><A href="http://blogs.msdn.com/mattwar/archive/2008/11/17/building-a-linq-iqueryable-provider-part-xii.aspx" mce_href="http://blogs.msdn.com/mattwar/archive/2008/11/17/building-a-linq-iqueryable-provider-part-xii.aspx">Part XII - Relationships and the IQ Toolkit</A><BR><A href="http://blogs.msdn.com/mattwar/archive/2009/01/22/building-a-linq-iqueryable-provider-part-xiii-iqtoolkit-v-0-13.aspx" mce_href="http://blogs.msdn.com/mattwar/archive/2009/01/22/building-a-linq-iqueryable-provider-part-xiii-iqtoolkit-v-0-13.aspx">Part XIII - Updates and Batch Processing</A><BR><A href="http://blogs.msdn.com/mattwar/archive/2009/04/08/building-a-linq-iqueryable-provider-part-xiv-iqtoolkit-v3.aspx" mce_href="http://blogs.msdn.com/mattwar/archive/2009/04/08/building-a-linq-iqueryable-provider-part-xiv-iqtoolkit-v3.aspx">Part XIV - Mapping and Providers</A><BR><A href="http://blogs.msdn.com/mattwar/archive/2009/06/16/building-a-linq-iqueryable-provider-part-xv-iqtoolkit-v0-15.aspx" mce_href="http://blogs.msdn.com/mattwar/archive/2009/06/16/building-a-linq-iqueryable-provider-part-xv-iqtoolkit-v0-15.aspx">Part XV -&nbsp;Transactions, Sessions and Factories</A><BR><A href="http://blogs.msdn.com/mattwar/archive/2009/09/15/building-a-linq-iqueryable-provider-part-xvi-iqtoolkit-0-16.aspx" mce_href="http://blogs.msdn.com/mattwar/archive/2009/09/15/building-a-linq-iqueryable-provider-part-xvi-iqtoolkit-0-16.aspx">Part XVI - Performance and Caching</A><BR><A href="http://blogs.msdn.com/mattwar/archive/2010/02/09/building-a-linq-iqueryable-provider-part-xvii-iqtoolkit-0-17.aspx" mce_href="http://blogs.msdn.com/mattwar/archive/2010/02/09/building-a-linq-iqueryable-provider-part-xvii-iqtoolkit-0-17.aspx">Part XVII - Automatic Caching and Loading Policies</A></P>
<P>The source code found in this series is also available at CodePlex.<BR><A href="http://www.codeplex.com/IQToolkit">http://www.codeplex.com/IQToolkit</A></P>
<P mce_keep="true">&nbsp;</P>]]></content:encoded>
    </item>
  </channel>
</rss>