我有一个查询,看起来像这样:
1 2 3 4 5 6 7 8 9 10
| public IList<Post> FetchLatestOrders(int pageIndex, int recordCount)
{
DatabaseDataContext db = new DatabaseDataContext();
return (from o in db.Orders
orderby o.CreatedDate descending
select o)
.Skip(pageIndex * recordCount)
.Take(recordCount)
.ToList();
} |
我需要打印订单的信息以及创建它的用户:
1 2 3 4
| foreach (var o in FetchLatestOrders(0, 10))
{
Console.WriteLine("{0} {1}", o.Code, o.Customer.Name);
} |
这将产生一个SQL查询来带来订单,并为每个订单带来一个查询来带来客户。 是否可以优化查询,以便在一个SQL查询中带来订单及其客户?
谢谢
UDPATE:通过sirrocco的建议,我像这样更改了查询,它可以正常工作。 仅生成一个选择查询:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public IList<Post> FetchLatestOrders(int pageIndex, int recordCount)
{
var options = new DataLoadOptions();
options.LoadWith<Post>(o => o.Customer);
using (var db = new DatabaseDataContext())
{
db.LoadOptions = options;
return (from o in db.Orders
orderby o.CreatedDate descending
select o)
.Skip(pageIndex * recordCount)
.Take(recordCount)
.ToList();
}
} |
谢谢你。
您还可以执行其他操作EagerLoading。在Linq2SQL中,您可以使用LoadOptions:有关LoadOptions的更多信息
关于L2S的一个非常奇怪的事情是,您只能在将第一个查询发送到数据库之前设置LoadOptions。
给定一个LINQ语句,例如:
1 2 3 4 5
| context.Cars
.OrderBy(x => x.Id)
.Skip(50000)
.Take(1000)
.ToList(); |
大致翻译成:
1
| select * from [Cars] order by [Cars].[Id] asc offset 50000 rows fetch next 1000 rows |
由于offset和fetch是order by的扩展,因此只有在select-portion运行之后才执行它们(google)。这意味着在获取获取结果之前,会对整个数据集([Cars])执行带有很多连接语句的昂贵选择。
优化陈述
所需要做的只是获取OrderBy,Skip和Take语句,并将它们放入Where子句中:
1 2 3
| context.Cars
.Where(x => context.Cars.OrderBy(y => y.Id).Select(y => y.Id).Skip(50000).Take(1000).Contains(x.Id))
.ToList(); |
大致翻译成:
1 2 3 4 5 6 7 8 9
| exec sp_executesql N'
select * from [Cars]
where exists
(select 1 from
(select [Cars].[Id] from [Cars] order by [Cars].[Id] asc offset @p__linq__0 rows fetch next @p__linq__1 rows only
) as [Limit1]
where [Limit1].[Id] = [Cars].[Id]
)
order by [Cars].[Id] asc',N'@p__linq__0 int,@p__linq__1 int',@p__linq__0=50000,@p__linq__1=1000 |
因此,现在,外部选择语句仅基于where存在子句在过滤后的数据集上执行!
同样,您的里程可能会因更改而节省多少查询时间。一般的经验法则是,选择语句越复杂,要进入的数据集越深,此优化就越有帮助。
您可能想研究使用编译查询
看看http://www.3devs.com/?p=3