Google
 
Showing posts with label LINQ. Show all posts
Showing posts with label LINQ. Show all posts

Sunday, April 4, 2010

LINQ to entities unncecessary casts

Using LINQ with Entity Framework can give a big productivity boost. It removes the burden of O/R mapping and writing SQL queries. But Adding this layer can come with costs.
I was writing a desktop application that uses a SQL CE database and I used LINQ to entities to talk to the database.
One of the methods was slow and I suspected that the reason can be a slow query. In normal, hand-written SQL queries, I inspect query plans to check the reason for the bad performance. So I started to log queries generated by LINQ statements using:

(myQuery as ObjectQuery).ToTraceString()

Then I took the SQL query from log file to SSMS and I started to make some enhancements. One of them was adding an index to a smallint column used in a foreign key. But I discovered that the index was not used by SQL CE. That was strange, but looking to the where statement generated I found something like:

WHERE ( CAST( [Extent1].[PageNumber] AS int)) = ( CAST( @p__linq__468 AS int))

And the index on the PageNumber column (smallint) was not used as I found from execution plan that filtering is made after a table scan (not index seek).
I suspected that the cast used in the above query is what caused the optimizer not to recognize that the index should be used, and I verified this by removing the cast and running the query in SSMS again. This time the index is being used.
I started to Google about this issue. But found that SQL Server is smart enough not to be tricked by the silly cast. But since I'm using SQL CE. I had to find a way to fix this issue.
Removing the unnecessary cast was out of my hands, so I decided to change the data type of the column to int and sacrifice some space to gain some speed. I did that and updated the model. And the where clause became:

WHERE [Extent1].[PageNumber] = ( CAST( @p__linq__468 AS int))

No casts for the PageNumber column and the index is used.

When you use a high level technology, you take it with its pros and cons. But there are no excuses, you are responsible for what you ship to your client.

Saturday, April 26, 2008

EDC: VS2008 New Enhancements

In this post I'll try to shed some light on what Chad Hower covered in his edc2008 session :"VS2008 New Enhancements".

The new keyword "var":
It's both used in LINQ expressions and when using anonymous types (more about them later). It also can be used in any regular variable declaration and initialization, for example:

StringBuilder b = new StringBuilder();
b.Append("abc");
var varB = new StringBuilder();
varB.Append("abc");


In the above example, var keyword was used instead of the StringBuilder class name in the second declaration. And the StringBuilder is used regularly. What worth mentioning is:


  • Some ex-vb developers may think that var is the same as the vb6 Variant datatype, which will cause some performace degradation when calling methods due to late binding. This is not true. The compiler replaces the var with the type initialized in the RHS. So the compiler output of these 2 lines is the same:

    StringBuilder b = new StringBuilder();

    var b = new StringBuilder();
    We just saved some keystrokes :).

  • VS2008 has full intellisense support for var. as you can see in the screenshot:


LINQ:

Using Language Integrated Query with collections can make many of programming tasks easier, like searching for an object or objects in a collection that meet a certain criteria.
For example, if we have a List< string > and we want to find all strings that start with the letter 'S', this is the old way to do this :

List< string > found=new List< string >();
foreach (string s in items)
{
if (s.StartsWith("S"))
found.Add(s);
}

Using LINQ:

var found = from s in items
where s.StartsWith("S")
select s;

Ok, more value can be gained if you need to get them sorted by length:

var found = from s in items
where s.StartsWith("S")
orderby s.Length
select s;


Some people may think that the 'var' keyword is what indicates a LINQ expression, but no, it's actually the 'from'.

A good place to think about using LINQ is where you usually use for and foreach.

LINQ is a new feature of C# v3.0 and VB.NET v9.0

Anonymous types:
I'll talk about Anonymous types usage in LINQ, although there are other cases when are useful.
In the above LINQ example, what if we don't need to get the result as a collection of complete objects of the original collection, and we just need one or two attributes (just as we can select just a few columns from a SQL database, not all columns from the table).
Anonymous types can be used in this case:

var found = from s in items
where s.StartsWith("S")
orderby s.Length
select new { value = s, length = s.Length };


Here, we created a new type on the fly, it has 2 properties: value which is a string and length which is an integer.
But how to iterate on found when we don't know the type of the objects it holds (remember, it's anonymous). This is where var comes to be useful again:

foreach (var s in found)
{
Console.WriteLine(s);
}



Others:
Chad talked about other thinks like OBA (Office Business Applications), WPF. The most important thing is that WPF works fine with Winforms. Winforms can host WPF components.

A very interesting presentation that Chad has shown for us was the History of Microsoft Office Download it and enjoy !!
Besides being funny, it shows how MS Office navigation had to evolve.


Chad just scratched the surface, but left us hungry for more knowledge about the existing new features.