【发布时间】:2011-09-23 13:43:55
【问题描述】:
我在使用 LINQ 生成的 Sql 查询时遇到了一些问题, 由于我的环境比较大,所以我做了一个简单的例子来反映我的问题。
这是我的模型:
public class ClassA
{
public int ID { get; set; }
public virtual ICollection<ClassB> Children { get; set; }
}
public class ClassB
{
public int ID { get; set; }
public string Data { get; set; }
}
public class ClassC
{
public int ID { get; set; }
public virtual ICollection<ClassB> Children { get; set; }
}
很简单吧?
嗯,这是我的查询:
var classA = (from x in db.ClassAs
where x.ID == 2
select x).First();
var classesB = (from b in classA.Children
select b.Data).Skip(10).Take(10);
classesB.ToList();
问题是当这个查询被翻译成 SQL 时:
(from x in db.ClassAs
where x.ID == 2
select x).First()
变成:
SELECT TOP (1)
[Extent1].[ID] AS [ID]
FROM [dbo].[ClassAs] AS [Extent1]
WHERE 2 = [Extent1].[ID]
和:
from b in classA.Children
select b.Data).Skip(10).Take(10)
变成:
SELECT
[Extent1].[ID] AS [ID],
[Extent1].[Data] AS [Data],
[Extent1].[ClassA_ID] AS [ClassA_ID]
FROM [dbo].[ClassBs] AS [Extent1]
WHERE ([Extent1].[ClassA_ID] IS NOT NULL) AND ([Extent1].[ClassA_ID] = @EntityKeyValue1)
我希望生成的查询是这样的:
SELECT [Data] AS [Data]
FROM (SELECT
[Data] AS [Data],
rownum = ROW_NUMBER() OVER (ORDER BY [B].[ID])
FROM ClassBs AS B , ClassAs AS A
WHERE B.ClassA_ID = A.ID
AND A.ID = 2) AS T1
WHERE [t1].rownum BETWEEN 11 AND 20
ORDER BY [t1].rownum
最大的问题是 Class A -> Class B 总是有超过 10k 行,而事实上,所有这些行都被加载到内存中,并且分页是在内存中进行的,但我希望此分页将由 SQL Server 完成。
关于如何实现这一点的任何想法?
【问题讨论】:
标签: c# sql-server linq query-optimization entity-framework-4.1