We use LINQ to SQL extensively, and one of the biggest performance pitfalls we've run into is situations where a query can't be converted to SQL, and so an entire database table gets loaded into memory and the query performed by .NET. For example, this query
Dim Foo = (From c in Db.Contacts Select c Where c.ContactID=MyContactID)
translates to a simple SQL query, whereas
Dim Foo = (From c in Db.Contacts Select c Where c.ContactID=SafeInt(MyContactID))
doesn't because SafeInt is our own function and doesn't have a SQL equivalent; so the whole contacts table gets loaded into memory and searched by LINQ to objects, which is vastly slower.
With a little experience, we've gotten better at avoiding this kind of situation. But it's not always obvious, and this is the sort of problem that's often not revealed until you're working with a lot of data and things start to slow down.
Is there a straightforward way to see - whether in Visual Studio or some other way - how LINQ queries will be handled, other than trial and error?