<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: When an object-relational mapper is too much, DataReader too little</title>
	<atom:link href="http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little/feed" rel="self" type="application/rss+xml" />
	<link>http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=when-an-object-relational-mapper-is-too-much-datareader-too-little</link>
	<description>A .NET developer in Redmond</description>
	<lastBuildDate>Tue, 31 Aug 2010 00:16:37 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
	<item>
		<title>By: Abusing dynamic for no good reason &#171; Searching, Seek and Deploy</title>
		<link>http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-37324</link>
		<dc:creator>Abusing dynamic for no good reason &#171; Searching, Seek and Deploy</dc:creator>
		<pubDate>Sun, 28 Feb 2010 16:54:49 +0000</pubDate>
		<guid isPermaLink="false">http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-37324</guid>
		<description>[...] Guard had a short post “When an object-relational mapper is too much, DataReader too little” along these lines and that’s what i have used as the basis for my dynamic abuse. In [...]</description>
		<content:encoded><![CDATA[<p>[...] Guard had a short post “When an object-relational mapper is too much, DataReader too little” along these lines and that’s what i have used as the basis for my dynamic abuse. In [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jimmy Zimmerman</title>
		<link>http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27474</link>
		<dc:creator>Jimmy Zimmerman</dc:creator>
		<pubDate>Mon, 05 Oct 2009 18:24:59 +0000</pubDate>
		<guid isPermaLink="false">http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27474</guid>
		<description>Yeah I actually hooked this guy up with another Ex Method from Alex (http://www.base4.net/blog.aspx?ID=409 which appears now to be DOA). Which was something along the lines of:

&lt;pre&gt;&lt;code&gt;&lt;b&gt;public static&lt;/b&gt; IEnumerable Enumerate(&lt;b&gt;this&lt;/b&gt; IDataReader reader) {
  &lt;b&gt;using&lt;/b&gt; (reader) 
    &lt;b&gt;while&lt;/b&gt; (reader.Read())
      &lt;b&gt;yield return&lt;/b&gt; reader;
}&lt;/code&gt;&lt;/pre&gt;

It seems logical that we really have two responsibilities here. One to enumerate a sequence of IDataRecord instances and another to coordinate with a mapping delegate and our friend the ExecuteReader() method.</description>
		<content:encoded><![CDATA[<p>Yeah I actually hooked this guy up with another Ex Method from Alex (<a href="http://www.base4.net/blog.aspx?ID=409" rel="nofollow">http://www.base4.net/blog.aspx?ID=409</a> which appears now to be DOA). Which was something along the lines of:</p>
<pre><code><b>public static</b> IEnumerable Enumerate(<b>this</b> IDataReader reader) {
  <b>using</b> (reader)
    <b>while</b> (reader.Read())
      <b>yield return</b> reader;
}</code></pre>
<p>It seems logical that we really have two responsibilities here. One to enumerate a sequence of IDataRecord instances and another to coordinate with a mapping delegate and our friend the ExecuteReader() method.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Damien Guard</title>
		<link>http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27409</link>
		<dc:creator>Damien Guard</dc:creator>
		<pubDate>Fri, 02 Oct 2009 00:29:16 +0000</pubDate>
		<guid isPermaLink="false">http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27409</guid>
		<description>@Jimmy: Good call, switched to IDataRecord :)</description>
		<content:encoded><![CDATA[<p>@Jimmy: Good call, switched to IDataRecord :)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jimmy Zimmerman</title>
		<link>http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27368</link>
		<dc:creator>Jimmy Zimmerman</dc:creator>
		<pubDate>Tue, 29 Sep 2009 22:57:04 +0000</pubDate>
		<guid isPermaLink="false">http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27368</guid>
		<description>The map function should be typed to a Func &lt;IDataRecord&gt; interface instead of the abstract DbDataReader class. One, the DbDataReader really is a bootstrap implementation of IDataReader and since you are really trying to perform reification of an object against a single &quot;row&quot;, you only need to expose the IDataRecord interface. I totally support the whole caveat emptor concept and that if someone does something stupid in the map delegate, like calling IDataReader.Read(), then that&#039;s their fault. However, I also strongly believe in the intention revealing interface. Basically if I see a parameter of type Foo in a delegate parameter definition, in theory all the operations available defined on Foo should be callable by me. That&#039;s not really the case here, you only want the IDataRecord members called (i.e.GetString(), GetInt32(), etc). Just my 2 cents.

-jimmy</description>
		<content:encoded><![CDATA[<p>The map function should be typed to a Func &lt;IDataRecord&gt; interface instead of the abstract DbDataReader class. One, the DbDataReader really is a bootstrap implementation of IDataReader and since you are really trying to perform reification of an object against a single &#8220;row&#8221;, you only need to expose the IDataRecord interface. I totally support the whole caveat emptor concept and that if someone does something stupid in the map delegate, like calling IDataReader.Read(), then that&#8217;s their fault. However, I also strongly believe in the intention revealing interface. Basically if I see a parameter of type Foo in a delegate parameter definition, in theory all the operations available defined on Foo should be callable by me. That&#8217;s not really the case here, you only want the IDataRecord members called (i.e.GetString(), GetInt32(), etc). Just my 2 cents.</p>
<p>-jimmy</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Damien Guard</title>
		<link>http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27256</link>
		<dc:creator>Damien Guard</dc:creator>
		<pubDate>Fri, 25 Sep 2009 00:32:28 +0000</pubDate>
		<guid isPermaLink="false">http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27256</guid>
		<description>@Matt Yes, AutoMapper might well be worth trying once the prototype gets a bit bigger :)

[)amien</description>
		<content:encoded><![CDATA[<p>@Matt Yes, AutoMapper might well be worth trying once the prototype gets a bit bigger :)</p>
<p>[)amien</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Matt Burton</title>
		<link>http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27246</link>
		<dc:creator>Matt Burton</dc:creator>
		<pubDate>Thu, 24 Sep 2009 20:02:32 +0000</pubDate>
		<guid isPermaLink="false">http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27246</guid>
		<description>Another option is Jimmy Bogard&#039;s AutoMapper - has support for IDataReader and IDataRecord built-in now. One line to map IDataReader to your type: &lt;code&gt;Mapper.CreateMap();&lt;/code&gt;

And another to do the map:

&lt;pre&gt;&lt;code&gt;&lt;strong&gt;var&lt;/strong&gt; customers = Mapper.Map&lt;IDataReader, IEnumerable&gt;(dataReader);&lt;/code&gt;&lt;/pre&gt;

Could probably bake that into your extension method style quite nicely:
&lt;pre&gt;&lt;code&gt;&lt;strong&gt;public static class&lt;/strong&gt; DataHelpers {
    &lt;strong&gt;public static&lt;/strong&gt; IEnumerable&lt;Customer&gt; As&lt;T&gt;(&lt;strong&gt;this &lt;/strong&gt;DbCommand command) {
        &lt;strong&gt;using&lt;/strong&gt; (&lt;strong&gt;var &lt;/strong&gt;reader = command.ExecuteReader(CommandBehavior.CloseConnection)) {
            &lt;strong&gt;return&lt;/strong&gt; Mapper.Map&lt;IDataReader, IEnumerable&gt;(dataReader);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;

Or heck, skip the CreateMap step if you don&#039;t need anything fancy (i.e. your domain object properties are 1-1 with column names) and change that line in the extension to this:

&lt;pre&gt;&lt;code&gt;&lt;strong&gt;return &lt;/strong&gt;Mapper.DynamicMap&lt;IDataReader, IEnumerable&gt;(dataReader);&lt;/code&gt;&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>Another option is Jimmy Bogard&#8217;s AutoMapper &#8211; has support for IDataReader and IDataRecord built-in now. One line to map IDataReader to your type: <code>Mapper.CreateMap();</code></p>
<p>And another to do the map:</p>
<pre><code><strong>var</strong> customers = Mapper.Map&lt;IDataReader, IEnumerable&gt;(dataReader);</code></pre>
<p>Could probably bake that into your extension method style quite nicely:</p>
<pre><code><strong>public static class</strong> DataHelpers {
    <strong>public static</strong> IEnumerable&lt;Customer&gt; As&lt;T&gt;(<strong>this </strong>DbCommand command) {
        <strong>using</strong> (<strong>var </strong>reader = command.ExecuteReader(CommandBehavior.CloseConnection)) {
            <strong>return</strong> Mapper.Map&lt;IDataReader, IEnumerable&gt;(dataReader);
        }
    }
}</code></pre>
<p>Or heck, skip the CreateMap step if you don&#8217;t need anything fancy (i.e. your domain object properties are 1-1 with column names) and change that line in the extension to this:</p>
<pre><code><strong>return </strong>Mapper.DynamicMap&lt;IDataReader, IEnumerable&gt;(dataReader);</code></pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Mike Levy</title>
		<link>http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27238</link>
		<dc:creator>Mike Levy</dc:creator>
		<pubDate>Thu, 24 Sep 2009 12:35:42 +0000</pubDate>
		<guid isPermaLink="false">http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27238</guid>
		<description>Give IBatis.Net a quick look: http://ibatis.apache.org/index.html</description>
		<content:encoded><![CDATA[<p>Give IBatis.Net a quick look: <a href="http://ibatis.apache.org/index.html" rel="nofollow">http://ibatis.apache.org/index.html</a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Rob</title>
		<link>http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27233</link>
		<dc:creator>Rob</dc:creator>
		<pubDate>Thu, 24 Sep 2009 07:52:46 +0000</pubDate>
		<guid isPermaLink="false">http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27233</guid>
		<description>isn&#039;t ToList already an extension method in System.Linq.Enumerable?</description>
		<content:encoded><![CDATA[<p>isn&#8217;t ToList already an extension method in System.Linq.Enumerable?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Kevin Babcock</title>
		<link>http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27228</link>
		<dc:creator>Kevin Babcock</dc:creator>
		<pubDate>Thu, 24 Sep 2009 03:23:40 +0000</pubDate>
		<guid isPermaLink="false">http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27228</guid>
		<description>While I like the approach, I agree with Zihotki: DbDataReader object should be closed as early as possible. This approach could hurt scalability.</description>
		<content:encoded><![CDATA[<p>While I like the approach, I agree with Zihotki: DbDataReader object should be closed as early as possible. This approach could hurt scalability.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Rob Conery</title>
		<link>http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27214</link>
		<dc:creator>Rob Conery</dc:creator>
		<pubDate>Wed, 23 Sep 2009 18:25:11 +0000</pubDate>
		<guid isPermaLink="false">http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27214</guid>
		<description>Well I was going to tell you that you could use SubSonic for this (sans code generation):

&lt;pre&gt;&lt;code&gt;&lt;strong&gt;var &lt;/strong&gt;customer = &lt;strong&gt;new&lt;/strong&gt; CodingHorror(&quot;SELECT * FROM Customer WHERE ID=@1&quot;,1).ExecuteSingle();&lt;/code&gt;&lt;/pre&gt;

But if you think FluentADO is &quot;too big&quot; then you might think SubSonic is as well :).</description>
		<content:encoded><![CDATA[<p>Well I was going to tell you that you could use SubSonic for this (sans code generation):</p>
<pre><code><strong>var </strong>customer = <strong>new</strong> CodingHorror("SELECT * FROM Customer WHERE ID=@1",1).ExecuteSingle();</code></pre>
<p>But if you think FluentADO is &#8220;too big&#8221; then you might think SubSonic is as well :).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Steve</title>
		<link>http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27211</link>
		<dc:creator>Steve</dc:creator>
		<pubDate>Wed, 23 Sep 2009 15:55:29 +0000</pubDate>
		<guid isPermaLink="false">http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27211</guid>
		<description>re extension methods: yeah, from a user perspective I can see it&#039;s useful not to have to hunt for non-member utility methods. I just have an old-fashioned resistance to having to totally rely on &#039;go to definition&#039; to navigate your codebase effectively, and I think it encourages a lack of design cohesion; like I say they&#039;re basically global utility functions, and if you did most things like that it wouldn&#039;t be considered a decent design approach (we did that in C years ago!). Hiding a global function by pretending it&#039;s a member is potentially fooling yourself into thinking that you have an OO design when you don&#039;t.</description>
		<content:encoded><![CDATA[<p>re extension methods: yeah, from a user perspective I can see it&#8217;s useful not to have to hunt for non-member utility methods. I just have an old-fashioned resistance to having to totally rely on &#8216;go to definition&#8217; to navigate your codebase effectively, and I think it encourages a lack of design cohesion; like I say they&#8217;re basically global utility functions, and if you did most things like that it wouldn&#8217;t be considered a decent design approach (we did that in C years ago!). Hiding a global function by pretending it&#8217;s a member is potentially fooling yourself into thinking that you have an OO design when you don&#8217;t.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Damien Guard</title>
		<link>http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27208</link>
		<dc:creator>Damien Guard</dc:creator>
		<pubDate>Wed, 23 Sep 2009 15:15:24 +0000</pubDate>
		<guid isPermaLink="false">http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27208</guid>
		<description>@zihotki - the reason I yield from each result there is I am actually foreach overing them and structuring them into a custom hierarchy at the other end - if I force them through a list then I&#039;d be building two structures. In a couple of places I want that - hence the ToList method as well.

FluentADO sounds like a nice idea but it is still too large for this little prototype and these methods are working a treat.

[)amien</description>
		<content:encoded><![CDATA[<p>@zihotki &#8211; the reason I yield from each result there is I am actually foreach overing them and structuring them into a custom hierarchy at the other end &#8211; if I force them through a list then I&#8217;d be building two structures. In a couple of places I want that &#8211; hence the ToList method as well.</p>
<p>FluentADO sounds like a nice idea but it is still too large for this little prototype and these methods are working a treat.</p>
<p>[)amien</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Damien Guard</title>
		<link>http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27206</link>
		<dc:creator>Damien Guard</dc:creator>
		<pubDate>Wed, 23 Sep 2009 14:57:21 +0000</pubDate>
		<guid isPermaLink="false">http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27206</guid>
		<description>@Steve I had those concerns about extension methods originally but if you accept the fact that just because there is a dot there doesn&#039;t mean it is necessarily a member of that class and use &quot;go to definition&quot; or hover to find out.

It really helps with discoverability - no more what class is that static method on that takes a string and does x with it? Well, it appears alongside x and it doesn&#039;t break encapsulation as it still only has access to the public interface.

[)amien</description>
		<content:encoded><![CDATA[<p>@Steve I had those concerns about extension methods originally but if you accept the fact that just because there is a dot there doesn&#8217;t mean it is necessarily a member of that class and use &#8220;go to definition&#8221; or hover to find out.</p>
<p>It really helps with discoverability &#8211; no more what class is that static method on that takes a string and does x with it? Well, it appears alongside x and it doesn&#8217;t break encapsulation as it still only has access to the public interface.</p>
<p>[)amien</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Travis</title>
		<link>http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27205</link>
		<dc:creator>Travis</dc:creator>
		<pubDate>Wed, 23 Sep 2009 14:55:27 +0000</pubDate>
		<guid isPermaLink="false">http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27205</guid>
		<description>Check out this project: http://fluentado.codeplex.com/</description>
		<content:encoded><![CDATA[<p>Check out this project: <a href="http://fluentado.codeplex.com/" rel="nofollow">http://fluentado.codeplex.com/</a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: pete w</title>
		<link>http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27199</link>
		<dc:creator>pete w</dc:creator>
		<pubDate>Wed, 23 Sep 2009 13:34:07 +0000</pubDate>
		<guid isPermaLink="false">http://damieng.com/blog/2009/09/22/when-an-object-relational-mapper-is-too-much-datareader-too-little#comment-27199</guid>
		<description>I understand your enthusiasm, I do a similar trick very often.
It is also easy to write some generic code that converts a DataTable to a collection of objects and vice versa.

Also, be sure to check out iBatis (think of it as the data-mapping functionality of NHibernate without all the session and reference stuff), this is good for building an ORM with legacy databases.

Also check out BLToolKit, which makes ORM dead simple for basic queries.</description>
		<content:encoded><![CDATA[<p>I understand your enthusiasm, I do a similar trick very often.<br />
It is also easy to write some generic code that converts a DataTable to a collection of objects and vice versa.</p>
<p>Also, be sure to check out iBatis (think of it as the data-mapping functionality of NHibernate without all the session and reference stuff), this is good for building an ORM with legacy databases.</p>
<p>Also check out BLToolKit, which makes ORM dead simple for basic queries.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
