[{"data":1,"prerenderedAt":407},["ShallowReactive",2],{"blog:2009:when-an-object-relational-mapper-is-too-much-datareader-too-little":3,"blogMore-Development":393,"comments-when-an-object-relational-mapper-is-too-much-datareader-too-little":406},{"id":4,"title":5,"body":6,"category":375,"commentCount":376,"date":377,"description":12,"excerpt":378,"extension":379,"filenames":380,"hidden":381,"image":380,"meta":382,"minutes":69,"navigation":240,"path":383,"seo":384,"showCategory":380,"stem":385,"tags":386,"updated":380,"url":390,"wordCount":391,"__hash__":392},"content\u002Fblog\u002F2009\u002Fwhen-an-object-relational-mapper-is-too-much-datareader-too-little.md","When an object-relational mapper is too much, DataReader too little",{"type":7,"value":8,"toc":373},"minimark",[9,13,16,132,139,142,360,363,369],[10,11,12],"p",{},"I fired up Visual Studio this evening to write a proof-of-concept app and found myself wanting strongly typed domain objects from a database but without the overhead of an object-relational mapper  (the application is read-only).",[10,14,15],{},"One solution is to write methods by hand, another is to code generate them but it would be nice to be able to do:",[17,18,23],"pre",{"className":19,"code":20,"language":21,"meta":22,"style":22},"language-csharp shiki shiki-themes everforest-light dracula","var customers = new SqlCommand(\"SELECT ID, Name FROM Customer\", connection)\n  .As(r => new Customer { CustomerID = r.GetInt32(0), Name = r.GetString(1) }).ToList();\n","csharp","",[24,25,26,67],"code",{"__ignoreMap":22},[27,28,31,35,39,43,47,51,54,58,62,64],"span",{"class":29,"line":30},"line",1,[27,32,34],{"class":33},"sXAHl","var",[27,36,38],{"class":37},"s6Vpi"," customers ",[27,40,42],{"class":41},"s9HRq","=",[27,44,46],{"class":45},"smiwp"," new",[27,48,50],{"class":49},"snuxY"," SqlCommand",[27,52,53],{"class":37},"(",[27,55,57],{"class":56},"sciFF","\"",[27,59,61],{"class":60},"sJQOs","SELECT ID, Name FROM Customer",[27,63,57],{"class":56},[27,65,66],{"class":37},", connection)\n",[27,68,70,73,77,79,83,86,88,91,94,96,99,102,104,108,111,113,115,118,120,123,126,129],{"class":29,"line":69},2,[27,71,72],{"class":37},"  .",[27,74,76],{"class":75},"sS4Kt","As",[27,78,53],{"class":37},[27,80,82],{"class":81},"s7cAX","r",[27,84,85],{"class":41}," =>",[27,87,46],{"class":45},[27,89,90],{"class":49}," Customer",[27,92,93],{"class":37}," { CustomerID ",[27,95,42],{"class":41},[27,97,98],{"class":37}," r.",[27,100,101],{"class":75},"GetInt32",[27,103,53],{"class":37},[27,105,107],{"class":106},"s3Ipq","0",[27,109,110],{"class":37},"), Name ",[27,112,42],{"class":41},[27,114,98],{"class":37},[27,116,117],{"class":75},"GetString",[27,119,53],{"class":37},[27,121,122],{"class":106},"1",[27,124,125],{"class":37},") }).",[27,127,128],{"class":75},"ToList",[27,130,131],{"class":37},"();\n",[10,133,134,135,138],{},"So for any ",[24,136,137],{},"DbCommand"," object you can turn it into a bunch of classes by specifying the new pattern.",[10,140,141],{},"The tiny helper class to achieve this is:",[17,143,145],{"className":19,"code":144,"language":21,"meta":22,"style":22},"public static class DataHelpers {\n  public static List\u003CT> ToList\u003CT>(this IEnumerable\u003CT> enumerable) {\n    return new List\u003CT>(enumerable);\n  }\n\n  public static IEnumerable\u003CT> As\u003CT>(this DbCommand command, Func\u003CIDataRecord, T> map) {\n    using (var reader = command.ExecuteReader())\n      while (reader.Read())\n        yield return map(reader);\n  }\n}\n",[24,146,147,165,212,229,235,242,295,320,334,349,354],{"__ignoreMap":22},[27,148,149,152,155,158,162],{"class":29,"line":30},[27,150,151],{"class":41},"public",[27,153,154],{"class":41}," static",[27,156,157],{"class":45}," class",[27,159,161],{"class":160},"sPLAf"," DataHelpers",[27,163,164],{"class":37}," {\n",[27,166,167,170,172,175,178,181,184,186,188,191,194,197,200,202,204,206,209],{"class":29,"line":69},[27,168,169],{"class":41},"  public",[27,171,154],{"class":41},[27,173,174],{"class":49}," List",[27,176,177],{"class":37},"\u003C",[27,179,180],{"class":49},"T",[27,182,183],{"class":37},"> ",[27,185,128],{"class":75},[27,187,177],{"class":37},[27,189,180],{"class":190},"sAO9U",[27,192,193],{"class":37},">(",[27,195,196],{"class":41},"this",[27,198,199],{"class":49}," IEnumerable",[27,201,177],{"class":37},[27,203,180],{"class":49},[27,205,183],{"class":37},[27,207,208],{"class":81},"enumerable",[27,210,211],{"class":37},") {\n",[27,213,215,218,220,222,224,226],{"class":29,"line":214},3,[27,216,217],{"class":45},"    return",[27,219,46],{"class":45},[27,221,174],{"class":49},[27,223,177],{"class":37},[27,225,180],{"class":49},[27,227,228],{"class":37},">(enumerable);\n",[27,230,232],{"class":29,"line":231},4,[27,233,234],{"class":37},"  }\n",[27,236,238],{"class":29,"line":237},5,[27,239,241],{"emptyLinePlaceholder":240},true,"\n",[27,243,245,247,249,251,253,255,257,259,261,263,265,267,270,273,276,279,281,284,286,288,290,293],{"class":29,"line":244},6,[27,246,169],{"class":41},[27,248,154],{"class":41},[27,250,199],{"class":49},[27,252,177],{"class":37},[27,254,180],{"class":49},[27,256,183],{"class":37},[27,258,76],{"class":75},[27,260,177],{"class":37},[27,262,180],{"class":190},[27,264,193],{"class":37},[27,266,196],{"class":41},[27,268,269],{"class":49}," DbCommand",[27,271,272],{"class":81}," command",[27,274,275],{"class":37},", ",[27,277,278],{"class":49},"Func",[27,280,177],{"class":37},[27,282,283],{"class":49},"IDataRecord",[27,285,275],{"class":37},[27,287,180],{"class":49},[27,289,183],{"class":37},[27,291,292],{"class":81},"map",[27,294,211],{"class":37},[27,296,298,301,304,306,309,311,314,317],{"class":29,"line":297},7,[27,299,300],{"class":45},"    using",[27,302,303],{"class":37}," (",[27,305,34],{"class":33},[27,307,308],{"class":37}," reader ",[27,310,42],{"class":41},[27,312,313],{"class":37}," command.",[27,315,316],{"class":75},"ExecuteReader",[27,318,319],{"class":37},"())\n",[27,321,323,326,329,332],{"class":29,"line":322},8,[27,324,325],{"class":45},"      while",[27,327,328],{"class":37}," (reader.",[27,330,331],{"class":75},"Read",[27,333,319],{"class":37},[27,335,337,340,343,346],{"class":29,"line":336},9,[27,338,339],{"class":45},"        yield",[27,341,342],{"class":45}," return",[27,344,345],{"class":75}," map",[27,347,348],{"class":37},"(reader);\n",[27,350,352],{"class":29,"line":351},10,[27,353,234],{"class":37},[27,355,357],{"class":29,"line":356},11,[27,358,359],{"class":37},"}\n",[10,361,362],{},"It might even be possible to do some cool caching\u002Fmaterialization. I should look into that :)",[10,364,365],{},[366,367,368],"em",{},"[)amien",[370,371,372],"style",{},"html pre.shiki code .sXAHl, html code.shiki .sXAHl{--shiki-default:#3A94C5;--shiki-dark:#FF79C6}html pre.shiki code .s6Vpi, html code.shiki .s6Vpi{--shiki-default:#5C6A72;--shiki-dark:#F8F8F2}html pre.shiki code .s9HRq, html code.shiki .s9HRq{--shiki-default:#F57D26;--shiki-dark:#FF79C6}html pre.shiki code .smiwp, html code.shiki .smiwp{--shiki-default:#F85552;--shiki-dark:#FF79C6}html pre.shiki code .snuxY, html code.shiki .snuxY{--shiki-default:#3A94C5;--shiki-default-font-style:inherit;--shiki-dark:#8BE9FD;--shiki-dark-font-style:italic}html pre.shiki code .sciFF, html code.shiki .sciFF{--shiki-default:#8DA101;--shiki-dark:#E9F284}html pre.shiki code .sJQOs, html code.shiki .sJQOs{--shiki-default:#8DA101;--shiki-dark:#F1FA8C}html pre.shiki code .sS4Kt, html code.shiki .sS4Kt{--shiki-default:#8DA101;--shiki-dark:#50FA7B}html pre.shiki code .s7cAX, html code.shiki .s7cAX{--shiki-default:#5C6A72;--shiki-default-font-style:inherit;--shiki-dark:#FFB86C;--shiki-dark-font-style:italic}html pre.shiki code .s3Ipq, html code.shiki .s3Ipq{--shiki-default:#DF69BA;--shiki-dark:#BD93F9}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sPLAf, html code.shiki .sPLAf{--shiki-default:#3A94C5;--shiki-dark:#8BE9FD}html pre.shiki code .sAO9U, html code.shiki .sAO9U{--shiki-default:#3A94C5;--shiki-default-font-style:inherit;--shiki-dark:#FFB86C;--shiki-dark-font-style:italic}",{"title":22,"searchDepth":69,"depth":69,"links":374},[],"Development",16,"2009-09-22T22:57:28+00:00","[object Object]","md",null,false,{},"\u002Fblog\u002F2009\u002Fwhen-an-object-relational-mapper-is-too-much-datareader-too-little",{"title":5,"description":12},"blog\u002F2009\u002Fwhen-an-object-relational-mapper-is-too-much-datareader-too-little",[387,388,389],".NET","SQL","C#","\u002Fblog\u002F2009\u002Fwhen-an-object-relational-mapper-is-too-much-datareader-too-little\u002F",321,"0-6Y03DDiRb3RpOCIdufswvrqSOhxv1259lmU2rW_Ys",[394,398,402],{"title":395,"date":396,"url":397},"Transactions in the MongoDB EF Core Provider","2025-10-25","\u002Fblog\u002F2025\u002Fmongodb-explicit-transactions\u002F",{"title":399,"date":400,"url":401},"Queryable Encryption with the MongoDB EF Core Provider","2025-09-22","\u002Fblog\u002F2025\u002Fmongodb-queryable-encryption\u002F",{"title":403,"date":404,"url":405},"Lazy Loading with EF Core Proxies","2025-04-02","\u002Fblog\u002F2025\u002Fef-proxies\u002F",[],1780900527397]