优化LINQ to SQL查询

7

我有一个查询看起来像这样:

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();
}

我需要打印订单信息和创建订单的用户信息:

foreach (var o in FetchLatestOrders(0, 10))
{
    Console.WriteLine("{0} {1}", o.Code, o.Customer.Name);
}

这将生成一个 SQL 查询来获取订单,并为每个订单生成一个查询来获取客户信息。有没有可能优化查询,使其在一个 SQL 查询中获取订单和客户信息呢?

谢谢。

更新:根据sirrocco的建议,我将查询更改如下,它可以正常工作。只生成一个选择查询:

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();
    }
}

感谢sirrocco的帮助。
3个回答

4

你还可以进行EagerLoading。在Linq2SQL中,你可以使用LoadOptions: 更多关于LoadOptions的信息 。一个非常奇怪的事情是,L2S只能在第一次查询发送到数据库之前设置LoadOptions。


哇,太棒了。我实现了这个,查询时间从25秒降到了1.5秒...非常棒的信息,谢谢。 - BastanteCaro
你能否回答一下这个问题:http://stackoverflow.com/questions/11262785/optimizing-repositorys-submitchanges-method? - LCJ

0

0

假设有一个类似于LINQ语句的:

context.Cars
  .OrderBy(x => x.Id)
  .Skip(50000)
  .Take(1000)
  .ToList();

这大致被翻译成:

select * from [Cars] order by [Cars].[Id] asc offset 50000 rows fetch next 1000 rows

由于偏移和获取是order by的扩展,它们直到select部分运行后才被执行(谷歌)。这意味着在获取结果之前,将在整个数据集([Cars])上执行具有许多联接语句的昂贵选择。

优化语句 需要做的就是将OrderBy、Skip和Take语句放入Where子句中:

context.Cars
  .Where(x => context.Cars.OrderBy(y => y.Id).Select(y => y.Id).Skip(50000).Take(1000).Contains(x.Id))
  .ToList();

这大致被翻译成:

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

现在,外部的选择语句只会在基于存在子句筛选后的数据集上执行!

再次强调,优化所节省的查询时间可能因情况而异。一般来说,如果你的选择语句越复杂,且需要深入数据集中的更深层级,这种优化将会更加有帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接