LINQ to SQL不会生成sargable查询

时间:2013-07-31 19:24:54

标签: c# .net linq-to-sql

我正在使用LINQ To Sql(非实体框架),System.Data.Linq.DataContext库,访问SQL Server 2005数据库并使用.Net Framework 4。

表dbo.Dogs有一个CHAR(1)NULL类的“Active”列。如果我直接写SQL,查询将是:

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

LINQ查询是这样的:

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

从上面的LINQ查询生成的SQL将Active字段转换为UNICODE。这意味着我无法在dbo.Dogs.Active列上使用索引,从而显着减慢查询速度:

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

我能做些什么来阻止Linq到Sql插入那个UNICODE()调用(从而失去了我对dogs.Active索引的好处)?我尝试使用EntityFunctions.AsNonUnicode()方法包装参数,但这没有用(它在生成的sql中将一个CONVERT()插入NVARCHAR而不是UNICODE()),例如:

...where d.Active.ToString() == EntityFunctions.AsNonUnicode('A'.ToString());

4 个答案:

答案 0 :(得分:4)

Linq旨在简化编写查询,并不总是生成最佳SQL。有时,当需要高性能时,直接针对数据库编写原始SQL更有效,Linq datacontext支持将SQL结果映射到实体,就像linq一样。 在你的情况下,我建议写:

IEnumerable<Dog> results = db.ExecuteQuery<Dog>(
                           "SELECT * FROM dbo.Dogs where Active = {0}", 
                           'A');

答案 1 :(得分:4)

这是一个老问题,但我最近碰到了这个问题。

而不是写

Scheduler

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

这将产生所需的SQL,而不必诉诸于任何&#34; hacks&#34;在其他答案中提到。我无法肯定地说出原因。

我已发布as a question,因此我们会看到我们是否得到了任何好的答案。

答案 2 :(得分:2)

LINQ查询转换为SQL语句的方式并不多,但您可以编写包含查询的存储过程,并将该SP称为LINQ2SQL函数。这样您就可以充分利用SQL Server优化

答案 3 :(得分:1)

你可以做一点点破解(因为LINQ to SQL和EF经常需要它)。在dbml中将属性声明为NCHAR。我希望这样就无需进行UNICODE转换。我们以良性的方式欺骗​​L2S。

也许您还需要插入EntityFunctions.AsNonUnicode调用以使右侧成为非unicode类型。

您还可以尝试将列映射为varchar