{"id":721,"date":"2008-02-14T23:55:00","date_gmt":"2008-02-14T23:55:00","guid":{"rendered":"\/blogs\/bobb\/post\/MHO-LINQ-to-SQL-and-Entity-Framework-Panacea-or-evil-incarnate-Part-2.aspx"},"modified":"2008-02-14T23:55:00","modified_gmt":"2008-02-14T23:55:00","slug":"mho-linq-to-sql-and-entity-framework-panacea-or-evil-incarnate-part-2","status":"publish","type":"post","link":"https:\/\/www.sqlskills.com\/blogs\/bobb\/mho-linq-to-sql-and-entity-framework-panacea-or-evil-incarnate-part-2\/","title":{"rendered":"MHO: LINQ to SQL and Entity Framework: Panacea or evil incarnate? Part 2"},"content":{"rendered":"<p>\nThis post covers LINQ to SQL and EF worry #2. That is:\n<\/p>\n<p>\nLINQ to SQL and EF will encourage &quot;SELECT * FROM&#8230;&quot; style coding because you get back a nice, clean object this way instead of the less-useful anonymous type you receive by doing projection. This will also make most\/all covering indexes useless.\n<\/p>\n<p>\nLINQ to SQL and EF can return something other than a whole object instance. Here&#39;s an example:\n<\/p>\n<p>\n\/\/ This returns a collection of authors<br \/>\nvar query =&nbsp; from a in ctx.authors<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select a;\n<\/p>\n<p>\n\/\/ this returns an anonymous type<br \/>\nvar query =&nbsp; from a in ctx.authors<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; join ta in ctx.titleauthors on a.au_id equals ta.au_id<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; join t in ctx.titles on ta.title_id equals t.title_id<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select new { a.au_id, t.title_id };\n<\/p>\n<p>\nThe collection of authors returned by the first query is updatable and a reference to it can be used outside the function in which its created. The anonymous type is not updatable and cannot be used outside the function in which its created (there is a nice workaround for this, but even the author of the workaround describes it as a bit of a hack). Although I can see a use for anonymous types in data-binding the good ol&#39; dropdown list. But because they&#39;re be can&#39;t insert a new row unless you include all the columns you need, perhaps not dropdown comboboxes.\n<\/p>\n<p>\nYou don&#39;t necessarily need to return an anonymous type. You can define (by hand) a class that represents the projection of authorid and titleid. Or use a view. But, in order to do this on a large-scale project, you&#39;d need to define a class for each projection in the entire project. Just for fun, I ask my students &quot;do you know every projection (rowset) that every query in your project returns&quot;? Can you even enumerate them? No one&#39;s answered &quot;yes&quot; to that question yet. So anonymous type (or much extra work). Maybe someone will write a tool to do this some day. Or &quot;whole objects&quot;&#8230;aka SELECT * FROM.\n<\/p>\n<p>\nCounter to this is perhaps you SHOULD know every projection your project returns. Would certain help in tuning to know them all.\n<\/p>\n<p>\nBTW, this is the same issue you&#39;d run into using stored procs that return rowsets with LINQ to SQL; they return anonymous types. Using rowset-returning procs with EF *forces* (in beta3) you to define a class to contain the rowset produced. That&#39;s good. But EF can&#39;t make use of procs that return more than 1 rowset (SqlDataReader.NextResult() in ADO.NET). LINQ to SQL can use these, you get multiple anonymous types.\n<\/p>\n<p>\nSo simple 1-rowset sprocs with EF, or custom classes for every projection (and sproc in LINQ to SQL) it is. Or nice, clean, full objects (using SELECT * FROM). And what about covering indexes? An overly-simplistic definition would be &quot;non-clusted index defined over the set of columns used by one table in a projection&quot;. Makes for some nice query plans (and sometimes even helps with concurrency issues in SELECTs). But if we&#39;re always doing SELECT * FROM, flush those covering indexes. The only index that matters is the (possibly) clustered index on the base table.\n<\/p>\n<p>\nA counter-argument to this is that you really shouldn&#39;t define a covering index for every projection just because you can. Any index takes space and affects insert\/updates\/deletes, there&#39;s a tradeoff here. A second counter-argument is that if you need many, many covering indexes, perhaps your database isn&#39;t as well normalized as it could be. I&#39;m not really sure I buy this argument.\n<\/p>\n<p>\nMHO: This is a for the mostpart a valid worry.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post covers LINQ to SQL and EF worry #2. That is: LINQ to SQL and EF will encourage &quot;SELECT * FROM&#8230;&quot; style coding because you get back a nice, clean object this way instead of the less-useful anonymous type you receive by doing projection. This will also make most\/all covering indexes useless. LINQ to [&hellip;]<\/p>\n","protected":false},"author":7,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,19,29],"tags":[],"class_list":["post-721","post","type-post","status-publish","format-standard","hentry","category-data-access","category-performance","category-sql-server-2008"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v21.9.1 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>MHO: LINQ to SQL and Entity Framework: Panacea or evil incarnate? Part 2 - Bob Beauchemin<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.sqlskills.com\/blogs\/bobb\/mho-linq-to-sql-and-entity-framework-panacea-or-evil-incarnate-part-2\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"MHO: LINQ to SQL and Entity Framework: Panacea or evil incarnate? Part 2 - Bob Beauchemin\" \/>\n<meta property=\"og:description\" content=\"This post covers LINQ to SQL and EF worry #2. That is: LINQ to SQL and EF will encourage &quot;SELECT * FROM&#8230;&quot; style coding because you get back a nice, clean object this way instead of the less-useful anonymous type you receive by doing projection. This will also make most\/all covering indexes useless. LINQ to [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.sqlskills.com\/blogs\/bobb\/mho-linq-to-sql-and-entity-framework-panacea-or-evil-incarnate-part-2\/\" \/>\n<meta property=\"og:site_name\" content=\"Bob Beauchemin\" \/>\n<meta property=\"article:published_time\" content=\"2008-02-14T23:55:00+00:00\" \/>\n<meta name=\"author\" content=\"Bob Beauchemin\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Bob Beauchemin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/mho-linq-to-sql-and-entity-framework-panacea-or-evil-incarnate-part-2\/\",\"url\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/mho-linq-to-sql-and-entity-framework-panacea-or-evil-incarnate-part-2\/\",\"name\":\"MHO: LINQ to SQL and Entity Framework: Panacea or evil incarnate? Part 2 - Bob Beauchemin\",\"isPartOf\":{\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/#website\"},\"datePublished\":\"2008-02-14T23:55:00+00:00\",\"dateModified\":\"2008-02-14T23:55:00+00:00\",\"author\":{\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/62bfa986c5b5d28fcffd8b4fc409c73e\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/mho-linq-to-sql-and-entity-framework-panacea-or-evil-incarnate-part-2\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.sqlskills.com\/blogs\/bobb\/mho-linq-to-sql-and-entity-framework-panacea-or-evil-incarnate-part-2\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/mho-linq-to-sql-and-entity-framework-panacea-or-evil-incarnate-part-2\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Data Access\",\"item\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/category\/data-access\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"MHO: LINQ to SQL and Entity Framework: Panacea or evil incarnate? Part 2\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/#website\",\"url\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/\",\"name\":\"Bob Beauchemin\",\"description\":\"SQL Server Blog\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/62bfa986c5b5d28fcffd8b4fc409c73e\",\"name\":\"Bob Beauchemin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/6f80e6cc667410857fa6a21931dc528b8092f4d112bf7a8ff7c267674d44ee37?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/6f80e6cc667410857fa6a21931dc528b8092f4d112bf7a8ff7c267674d44ee37?s=96&d=mm&r=g\",\"caption\":\"Bob Beauchemin\"},\"sameAs\":[\"http:\/www.sqlskills.com\/blogs\/bobb\/\"],\"url\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/author\/bobb\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"MHO: LINQ to SQL and Entity Framework: Panacea or evil incarnate? Part 2 - Bob Beauchemin","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.sqlskills.com\/blogs\/bobb\/mho-linq-to-sql-and-entity-framework-panacea-or-evil-incarnate-part-2\/","og_locale":"en_US","og_type":"article","og_title":"MHO: LINQ to SQL and Entity Framework: Panacea or evil incarnate? Part 2 - Bob Beauchemin","og_description":"This post covers LINQ to SQL and EF worry #2. That is: LINQ to SQL and EF will encourage &quot;SELECT * FROM&#8230;&quot; style coding because you get back a nice, clean object this way instead of the less-useful anonymous type you receive by doing projection. This will also make most\/all covering indexes useless. LINQ to [&hellip;]","og_url":"https:\/\/www.sqlskills.com\/blogs\/bobb\/mho-linq-to-sql-and-entity-framework-panacea-or-evil-incarnate-part-2\/","og_site_name":"Bob Beauchemin","article_published_time":"2008-02-14T23:55:00+00:00","author":"Bob Beauchemin","twitter_misc":{"Written by":"Bob Beauchemin","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/mho-linq-to-sql-and-entity-framework-panacea-or-evil-incarnate-part-2\/","url":"https:\/\/www.sqlskills.com\/blogs\/bobb\/mho-linq-to-sql-and-entity-framework-panacea-or-evil-incarnate-part-2\/","name":"MHO: LINQ to SQL and Entity Framework: Panacea or evil incarnate? Part 2 - Bob Beauchemin","isPartOf":{"@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/#website"},"datePublished":"2008-02-14T23:55:00+00:00","dateModified":"2008-02-14T23:55:00+00:00","author":{"@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/62bfa986c5b5d28fcffd8b4fc409c73e"},"breadcrumb":{"@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/mho-linq-to-sql-and-entity-framework-panacea-or-evil-incarnate-part-2\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.sqlskills.com\/blogs\/bobb\/mho-linq-to-sql-and-entity-framework-panacea-or-evil-incarnate-part-2\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/mho-linq-to-sql-and-entity-framework-panacea-or-evil-incarnate-part-2\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.sqlskills.com\/blogs\/bobb\/"},{"@type":"ListItem","position":2,"name":"Data Access","item":"https:\/\/www.sqlskills.com\/blogs\/bobb\/category\/data-access\/"},{"@type":"ListItem","position":3,"name":"MHO: LINQ to SQL and Entity Framework: Panacea or evil incarnate? Part 2"}]},{"@type":"WebSite","@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/#website","url":"https:\/\/www.sqlskills.com\/blogs\/bobb\/","name":"Bob Beauchemin","description":"SQL Server Blog","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.sqlskills.com\/blogs\/bobb\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/62bfa986c5b5d28fcffd8b4fc409c73e","name":"Bob Beauchemin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/6f80e6cc667410857fa6a21931dc528b8092f4d112bf7a8ff7c267674d44ee37?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/6f80e6cc667410857fa6a21931dc528b8092f4d112bf7a8ff7c267674d44ee37?s=96&d=mm&r=g","caption":"Bob Beauchemin"},"sameAs":["http:\/www.sqlskills.com\/blogs\/bobb\/"],"url":"https:\/\/www.sqlskills.com\/blogs\/bobb\/author\/bobb\/"}]}},"_links":{"self":[{"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/posts\/721","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/comments?post=721"}],"version-history":[{"count":0,"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/posts\/721\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/media?parent=721"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/categories?post=721"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/tags?post=721"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}