Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ to SQL will not generate sargable query

I'm using LINQ To Sql (not Entity Framework), the System.Data.Linq.DataContext library, hitting a SQL Server 2005 database and using .Net Framework 4.

The table dbo.Dogs has a column "Active" of type CHAR(1) NULL. If I was writing straight SQL the query would be:

SELECT * FROM dbo.Dogs where Active = 'A';

The LINQ query is this:

from d in myDataContext.Dogs where d.Active == 'A' select d;

The SQL that gets generated from the above LINQ query converts the Active field to UNICODE. This means I cannot use the index on the dbo.Dogs.Active column, slowing the query significantly:

SELECT [t0].Name, [t0].Active
FROM [dbo].[Dog] AS [t0]
WHERE UNICODE([t0].[Active]) = @p1

Is there anything I can do to stop Linq to Sql from inserting that UNICODE() call (and thus losing the benefit of my index on dogs.Active)? I tried wrapping the parameters using the EntityFunctions.AsNonUnicode() method, but that did no good (it inserted a CONVERT() to NVARCHAR instead of UNICODE() in the generated sql), eg:

...where d.Active.ToString() == EntityFunctions.AsNonUnicode('A'.ToString());
like image 356
Tom Regan Avatar asked Jul 31 '13 19:07

Tom Regan


People also ask

How LINQ queries converted into SQL queries?

LINQ to SQL translates the queries you write into equivalent SQL queries and sends them to the server for processing. More specifically, your application uses the LINQ to SQL API to request query execution. The LINQ to SQL provider then transforms the query into SQL text and delegates execution to the ADO provider.

When LINQ query is executed?

LINQ queries are always executed when the query variable is iterated over, not when the query variable is created. This is called deferred execution. You can also force a query to execute immediately, which is useful for caching query results. This is described later in this topic.

What is LINQ query in SQL Server?

In LINQ to SQL, the data model of a relational database is mapped to an object model expressed in the programming language of the developer. When the application runs, LINQ to SQL translates into SQL the language-integrated queries in the object model and sends them to the database for execution.


1 Answers

Linq is meant to make it easier to write queries and does not always generate optimal SQL. Sometimes when high performance is required it is more efficient to write raw SQL directly against the database, the Linq datacontext supports mapping of SQL result to entities just like linq. In your case I would suggest writing:

IEnumerable<Dog> results = db.ExecuteQuery<Dog>(
                           "SELECT * FROM dbo.Dogs where Active = {0}", 
                           'A');
like image 187
Magnus Avatar answered Oct 04 '22 17:10

Magnus