13

我正在使用 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 to Sql 插入该 UNICODE() 调用(从而失去我对 dogs.Active 的索引的好处)?我尝试使用 EntityFunctions.AsNonUnicode() 方法包装参数,但这没有用(它在生成的 sql 中将 CONVERT() 插入到 NVARCHAR 而不是 UNICODE() ),例如:

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

4 回答 4

4

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

IEnumerable<Dog> results = db.ExecuteQuery<Dog>(
                           "SELECT * FROM dbo.Dogs where Active = {0}", 
                           'A');
于 2013-07-31T21:55:08.753 回答
4

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

而不是写

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

from d in myDataContext.Dogs where d.Active.Equals('A') select d;

这将产生所需的 SQL,而不必求助于其他答案中提到的任何“黑客”。我不能肯定地说为什么。

我已经把它作为一个问题发布了,所以我们会看看我们是否能得到任何好的答案。

于 2016-03-07T21:49:09.673 回答
2

对于将 LINQ 查询转换为 SQL 语句的方式,您无能为力,但您可以编写一个包含查询的存储过程,并将该 SP 作为 LINQ2SQL 函数调用。这样您就可以充分利用 SQL Server 优化

于 2013-07-31T21:30:30.227 回答
1

You can do a little hack (as it is often required with LINQ to SQL and EF). Declare the property as NCHAR in the dbml. I hope that will remove the need to do the UNICODE conversion. We are tricking L2S in a benign way with that.

Maybe you need to also insert the EntityFunctions.AsNonUnicode call to make the right hand side a non-unicode type.

You can also try mapping the column as varchar.

于 2013-07-31T21:49:31.600 回答