loads of useful information, examples and tutorials pertaining to web development utilizing asp.net, c#, vb, css, xhtml, javascript, sql, xml, ajax and everything else...

 



Advertise Here
C-Sharpener.com - Programming is Easy!  Learn Asp.Net & C# in just days, Guaranteed!

Linq-to-SQL vs Linq-to-Entities : Revisited

by naspinski 5/6/2009 7:24:00 AM

After 2 months of nothing but L2E, I feel I can give a decent comparison

Most likely you have read more than just a few of these comparisons and are tired of the debate. I too disliked L2E from the get-go but decided that my opinion was not totally grounded and that I should really understand L2E before I crap on it, so, I decided to do an entire project at work with it and get down to the nuts and bolts. Now, 2 months, a lot of frustration and some happy customers later, I can give a fully educated opinion on L2E: it is not as bad as I originally thought, in fact, it is pretty sweet in some areas, but still not as easy to use as L2S.

If you have read any of my multiple posts on Entities this will mostly be a re-hash of what I have already said. If not, this is a good summary of my findings and hopefully will help you decide.

dynamic queries

Winner: TIE
Thanks to the geniuses that wrote System.Linq.Dynamic.dll the syntax is *mostly* interchangable between the two languages (which I didn't realize when writing this). If I was forced to pick a winner, it would be L2S as there are more choices for syntax than for L2E, but that can also be viewed as a fault.

linq-to-sql -and- linq-to-entities
var results = db.branch
  .Where("branch_id == @0 || display == @1", 
    new object[] {5, "Hello"});

With L2S, you can do this as well:
var results = db.branch
  .Where("branch_id == 5 || display == \"Hello\"");

working with databound controls

Winner: Linq-to-SQL
This one is a no-brainer. After being lulled into the fact that L2S just works with so many things, I had to work backwards on problems I found with L2E. One annoyance I noticed was that if I was making an update in a GridView, it would error out unless I explicitly had the primary key in the GridView - and if I wanted it hidden, it was necessary to use css; it is documented here.

Another thing I ran across is the fact that you need to use all the required 'Include' statements in order to get a Repeater/GridView to show child values of relationships with Entities where is L2S, you could simply call the relation without any extra work.

multiple databases

Winner: Linq-to-SQL
The choice is quite simple here, as Linq-to-Entities has no native support for multiple databases.

database relation management

Winner: Linq-to-SQL
First of all, simple things such as getting foreign key values with linq-to-entities is much more difficult than in L2S; examples (written as short as I could):

linq-to-sql
int s_id = dataContext.records
  .First(r => r.record_id == 1).state_id;

linq-to-entities
int s_id = Convert.ToInt32(
  Entities.records.First(r => r.record_id == 1)
    .stateReference.EntityKey
    .EntityKeyValues.First().Value
  );

As for putting those relation values into the DB, the clear winner is L2S as well, just take a look at what it takes to set this object 'r' to have a reference to the 'city' which has a key of the integer value of 5:

linq-to-sql
r.city_id = 5;

linq-to-entities
r.cityReference.EntityKey = new EntityKey(
  "YourEntitiesNamespace.cities", "city_id", 5);

a few more...

A while back I went over some other reasons L2E annoyed me such as DataSource annoyances, relations (again) and the pain of updating your model.

verdict

Linq-to-Entities is fully capable and can do *almost* everything Linq-to-SQL can do, it just takes a bit more code some times; the almost is for multiple database utilization. L2E is a great ORM, but many of us were spoiled with L2S, so it is now up to Microsoft to live up to the expectations that they put out for us with this framework that they are deprecating. I hope and assume it will become a superior ORM, but that is in Microsoft's hands now; for the time being, it is not.

Shout it kick it on DotNetKicks.com

Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.

by naspinski 4/21/2009 12:24:00 PM

Confusing error while using an EntityDataSource with a GridView update

Linq-to-Entities baffled me yet again today. I was simply trying to bind an EntityDataSource to a GridView then do an update. It worked as expected, even with the foreign keys... but that was only if I used the auto-generated columns. When I tried to make the fields myself with TemplateFields, all hell broke loose and this error popped up.

While this may make sense to some people, it made none to me, so I basically just started changing things one-by-one until something broke. When I changed AutoGenerateColumns to 'false' it would break. But... if I added in a BoundField that had the primary key in it, it would work? Ok, great, but I didn't want the user to see the primary key field, they don't care about it, so I set that BoundField to Visible="false"; it broke again.

solution

You need to explicitly include a BoundField of the primary key! Since I didn't want the user to see my primary key, I had to resort to hiding it via css:

<asp:BoundField DataField="my_primary_key" ItemStyle-CssClass="hidden" HeaderStyle-CssClass="hidden" />


Where 'hidden' is a class in css that has it's display set to 'none'. Not sure why Entities can't figure this out like all the other DataSources...

You might be making a lot of unneccessary trips to your DB with Linq-to-SQL

by naspinski 2/6/2009 4:43:00 AM

Linq-to-SQL has great use of relations, but lazy loading can cause a huge amount of trips to your DB - implementing eager loading is one answer

After my rant on L2E, Dan from Microsoft got back to me in the comments and pointed out a lot of what I wanted to know. One thing that he brought up was the use of eager loading which I hadn't looked in to; turns out it can be VERY important!

Let's say you are using a GridView and for each row, you are using a relation to the 'states' table to pull the name of a 'state' object:
<asp:BoundField DataField="item.state.state_name" HeaderText="State Name" SortExpression="item.state.state_name" />

Now this will work just fine, but each time you add a row, there is going to be another call to the DB to get the state name. Now if you only have a few rows, no big deal, but what if you are calling 100 records each with a a call to the state name and a country name? It is no longer one trip to get the items, it grows huge! Here is some ugly psuedo-code for understanding:
ONE_SQL_QUERY -> 100_ROWS_RETURNED (1 trip)
FOREACH(ROW row in 100_ROWS_RETURNED)
{
  QUERY_FOR_STATE_NAME (1 trip)
  QUERY_FOR_COUNTRY_NAME (1 trip)
}

That one query has now jumped to 201 database calls (1+100(1+1)) ... that is no small difference! Now, that first query, no matter how big and ugly it is is dwarfed by these petty little calls for one small string. Just imagine what happens if you are calling multiple and nested relations, that one call can easily jump to well over 1000 in no time.

So what to do?

While searching on Linq-to-Entities (yes, I still want to make the switch some time) I came across this: http://blogs.msdn.com/adonet/archive/2008/10/07/migrating-from-linq-to-sql-to-entity-framework-eager-loading.aspx which shows how you deal with this in both L2S and L2E (also answered my last question on my rant against L2E. This is actually a situation where (I think) L2E shines over L2S, but that's a whole other debate. Here is what you would need to do.
dbDataContext db = new dbDataContext();
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<item>(i => i.state);
dlo.LoadWith<item>(i => i.country);
db.LoadOptions = dlo;

What this is doing is telling your DataContext to load those other elements with your every 'item' you load (don't forget to include using System.Data.Linq;). This will obviously make for a larger query to begin with, but it will cut out those multiple return trips that are the real problem!

On an somewhat related note... I am going to force myself to use L2E on my next project.

Slick-Ticket Trouble Ticketing/Help Desk System

by naspinski 1/19/2009 3:25:00 AM

My first Open-Source Project!

This is a simple, to-the-point system. It was born out of loathing of the system that I was forced to use. It was tested in a live environment with hundreds of users and ultimately de-throned our expensive and bloated ticketing software. I really enjoyed developing this and my users and I really enjoy using it, I hope some other people out there like it.
  • Full Integrated with Active Directory means not another layer of permissions to add
  • Intuitive interface allows users to jump right in
  • Integrated help/faq system for administrators to inform users

Details

  • Utilizes .Net 3.5 (C#)
  • Asp.Net architecture built with Linq-to-SQL
  • Utilizes Asp.Net AJAX and the AJAX Control Toolkit
  • Completely customizable colors/themes
  • Installation program included, just load it on your machine and follow the directions

Requirements

  • SQL 2005 Database (SQLExpress works fine)
  • .Net 3.5
  • Active Directory

It is available for download at CodePlex. I also have a site up at http://slick-ticket.com with a demo site soon on the horizon.

Screenshots (Click for full-size images)

Settings interface for the administrator, including the theme customizer Adding a new ticket User profile, most data is pulled directly frorm AD (though you can change it)
*Also notice the different style with the sidebar on the opposite side
Integrated FAQ/Help section for information sharing Easy interface to view the tickets you are interested in View/comment a ticket in progress
*This is Licensed under the GNU General Public License version 2 (GPLv2)

Shout it kick it on DotNetKicks.com

Why I decided to stick with Linq-to-SQL over Linq-to-Entities

by naspinski 1/17/2009 1:09:00 PM

I tried to make the switch... but Linq-to-Entities is just so much more work!

Recently I tried, I really tried to like L2E, but I just can't do it! It adds layer upon layers of extra crap I have to do over L2S while offering little to no improvements over the soon to be deprecated ORM. I am officially sticking with L2S until they get L2E better developed. Now I am hardly the first person to write about this, but I feel my concrete examples are somewhat helpful when trying to decide.

Now I have read a bunch of reason of why not to switch, but I stubbornly went along and tried it myself. I like to dumb down my reasons to simple examples of why I have come to loathe L2E (these are all using the same exact DB):

DataSources

I'll just show you on this one, it may not seem like a lot, but try it for yourself and see how confusing the syntax can get:

Linq-To-Entities

<asp:EntityDataSource ID="edsState" runat="server"
  ConnectionString="name=J1Entities"
  DefaultContainerName="J1Entities"
  EntitySetName="state" Select="it.[state_id], it.[state_name]">

Linq-to-SQL

<asp:LinqDataSource ID="ldsState" runat="server"
  ContextTypeName="dbDataContext"
  Select="new (state_id, state_name)" TableName="states" />

Now I don't know about you, but the L2S is just easier to understand. Why the hell do I have to use it.[column_name]? That doesn't make any sense. Not to mention the GUI may as well not be there if you are trying to use automatic Delete, Update or Insert.

Relations

This one is HUGE! Let's say you have a Foreign Key relation of state_id that relates to a table states and Primary Key that is also named state_id; here is how you do that in both frameworks:

Linq-To-Entities

item itm = new item() { item_name = "party" };
itm.state = db.state.First(s => s.state_id = 5));
db.AddToitem(itm);
db.SaveChanges();

Linq-to-SQL

item itm = new item() { item_name = "party", state_id = 5 };
db.items.InsertOnSubmit(itm);
db.SubmitChanges();

Now this is a super abbreviated case, but you can see the huge amount of overhead this can create not to mention programming time. I made these as succinct as I could not to try to advantage one over the other and the L2E is just burdensome. Even if I were to make a simple Get() method for state it would still make another call to the DB when I already know the relation integer!!! What an unnecessary step. And this extra work increases like crazy on large object with multiple relations.

Updating your Model

Now I can't relaly show this as an example, so I will just try to explain it. One big pain (I thought) in L2S was the fact that you had to pull your tables back in to your dbml every time you made a change to the DB (I know there are tools for this, but I am talking stock). L2E had this nifty feature that allowed you to 'refresh from the database' that I thought would actually work. The problem is, that if you change anything with any complexity whatsoever, like a Foreign Key, or even something as simple as changing a data type from VARCHAR to INT it seems to completely break your edmx. And this isn't simple to fix like a dbml, not even close. You can't drag a table into a edmx, and you can't seem to fix it through the refresh so what do you do?
  • Delete your edmx completely
  • Go into your web.config and delete the ConnectionString (unless you want duplicates)
  • Completely remake your edmx
  • Redo any changes in the crappy naming conventions to ALL of your tables that you changed (more on this later)
Wow... all that because I changed a relation? No thank you. Dragging that table into the dbml doesn't seem so bad now.

Relations Part 2

This one isn't as big of a deal, but it is annoying.

Linq-To-Entities

item itm = db.item.First(i => i.item_id == 12);
itm.stateReference.Load()
string whatState = itm.stateReference.Value.state_name;

Linq-to-SQL

item itm = db.items.First(i => i.item_id == 12);
string whatState = itm.state.state_name;

Just simpler in L2S and you don't have to remember the Load() if you forget, and it's in a lot of code, it can be extremely aggravating wondering why your relation is empty. Not to mention that reference.value syntax in there... more unnecessary (in my eyes) crap.

Relations Part 3

And this was the straw that broke the camels back... I was so used to the simplicity and convenience of L2S that this drove me nuts and was the reason I decided to give up. Relations are used so well with L2S that to show relations in something like a Repeater or GridView is almost trivially easy

Linq-To-Entities

Who knows?!

Linq-to-SQL

<asp:BoundField DataField="item.state.state_name" HeaderText="State Name" SortExpression="item.state.state_name" />

but since L2E requires that wonderful Load() method, it is now not so easy - to tell you the truth, I never figured it out how to make it work, probably have to call something on the RowDataBound event, but at this point I figured what is the point?

I am officially resigning from L2E (for now) and going back to L2S... maybe next go-round L2E won't be such a pain? Isn't new technology supposed to make our lives easier? Going from L2S to L2E is like 'upgrading' from a blender to a hand-mixer; it will get done, it will just take you longer and be more frustrating. Hopefully, considering that is the was MS is heading.

Shout it kick it on DotNetKicks.com