C# Linq to Entities 4.0-优化查询和在单个查询中多次调用数据库

C# Linq to Entities 4.0-优化查询和在单个查询中多次调用数据库,c#,linq,.net-4.0,linq-to-entities,subquery,C#,Linq,.net 4.0,Linq To Entities,Subquery,有谁能告诉我下面的查询是多次调用数据库还是只调用一次 var bizItems = new { items = ( from bl in db.rc_BusinessLocations orderby bl.rc_BusinessProfiles.BusinessName select new BusinessLocationItem { BusinessLocation = bl,

有谁能告诉我下面的查询是多次调用数据库还是只调用一次

var bizItems = new
{
    items = (
        from bl in db.rc_BusinessLocations
        orderby bl.rc_BusinessProfiles.BusinessName
        select new BusinessLocationItem
        {
            BusinessLocation = bl,
            BusinessProfile = bl.rc_BusinessProfiles,
            Products = bl.rc_InventoryProducts_Business
        })
        .Skip(pageSkip).Take(pageSize),

    Count = db.rc_BusinessLocations.Count()
};
我真的需要从查询中获取Count(),但我找不到其他方法来实现它。如果您有更好的优化代码,请随意分享

提前谢谢


Gwar肯定会导致两个调用。

这肯定会导致两个调用。

您应该查看Scott Guthrie关于使用LINQ to SQL调试可视化工具的介绍。这将允许您准确地看到将从LINQ语句生成的SQL

您应该查看Scott Guthrie关于使用LINQ to SQL调试可视化工具的文章。这将允许您准确地看到将从LINQ语句生成的SQL

这完全取决于您对
bizItems
变量所做的操作,因为在您只运行此代码之后,将只运行
COUNT(*)
查询。这是因为
包含一个
IQueryable
,它是对查询的描述(运行的意图),而不是操作的结果。只有当您使用
foreach
.Count()等运算符开始迭代此查询时,查询才会运行。除此之外,
BusinessProfile
Products
属性也可能包含
IQueryable
s

这样,让我们来看看你可能对这个代码做些什么:

foreach (var item in bizItems.items)
{
    Console.WriteLine(item.BusinessLocation.City);

    foreach (var profile in item.BusinessProfile)
    {
        Console.WriteLine(profile.Name);
    }

    foreach (var product in item.Products)
    {
        Console.WriteLine(product.Price);
    }

    Console.WriteLine(item.Count);
    Console.WriteLine();
}

所以,如果你再问我一次,看看这段代码,有多少查询将被发送到数据库,我的答案是:2+2*bizItems.items中的项目数。因此,查询的数量将介于2和(2+2*pageSize)之间。

这完全取决于您使用
bizItems
变量所做的操作,因为在您只运行此代码之后,将只运行
COUNT(*)
查询。这是因为
包含一个
IQueryable
,它是对查询的描述(运行的意图),而不是操作的结果。只有当您使用
foreach
.Count()等运算符开始迭代此查询时,查询才会运行。除此之外,
BusinessProfile
Products
属性也可能包含
IQueryable
s

这样,让我们来看看你可能对这个代码做些什么:

foreach (var item in bizItems.items)
{
    Console.WriteLine(item.BusinessLocation.City);

    foreach (var profile in item.BusinessProfile)
    {
        Console.WriteLine(profile.Name);
    }

    foreach (var product in item.Products)
    {
        Console.WriteLine(product.Price);
    }

    Console.WriteLine(item.Count);
    Console.WriteLine();
}

所以,如果你再问我一次,看看这段代码,有多少查询将被发送到数据库,我的答案是:2+2*bizItems.items中的项目数。因此,查询的数量将介于2和(2+2*pageSize)之间。

我很清楚,您需要的是数据库中所有rc_业务位置的计数,而不是放入项目的计数。正确吗?是的,这是正确的。我应该提到,这将用于分页,因此我需要在页面上显示一个子集,但分页器组件需要知道全局存在多少项(显示[total_count]项的x到y项)。上面的代码工作得很好,但我只是想知道我是否对数据库进行了两次单独的调用。。。谢谢我很清楚,你需要的是数据库中所有rc_业务地点的计数,而不是放入项目的计数,对吗?是的,这是正确的。我应该提到,这将用于分页,因此我需要在页面上显示一个子集,但分页器组件需要知道全局存在多少项(显示[total_count]项的x到y项)。上面的代码工作得很好,但我只是想知道我是否对数据库进行了两次单独的调用。。。谢谢史蒂文,这是一个非常翔实的答案。我不知道查询被优化了多少,即使是在事实发生之后。因此,基本上,如果我正确理解您的回答,就无法知道将对数据库进行多少次调用,除非您确切知道(预期的)结果是如何使用的。。谢谢不得不将我的评论分成两部分..--我想,唯一剩下的问题是:有没有更好的方法来优化我发布的查询?我希望能够像在SQL中使用“Count(1)和TotalCount”一样创建临时变量。似乎我只需要接受Linq,并希望它能做得很好,因为数据库调用依赖于查询和以后使用的混合。。有什么想法吗?@Gwar:我建议你试着去理解LINQ是如何工作的,因为你不必“仅仅希望它做得很好”。在单个数据库查询中执行
计数和主结果可能很困难,但是,通过使用匿名类型和LINQ to Entities提供的优化,可以阻止所有这些“子”查询执行。@Gwar:如果您发现性能太慢,无法对其进行优化,在这里发布一个新问题,包括查询和用法等。可能还包括
DataContext.Log
的输出到您的问题中。如果你能很好地表达你的问题,就会有足够多的人来帮助你。史蒂文,这是一个非常翔实的答案。我不知道查询被优化了多少,即使是在事实发生之后。因此,基本上,如果我正确理解您的回答,就无法知道将对数据库进行多少次调用,除非您确切知道(预期的)结果是如何使用的。。谢谢不得不将我的评论分成两部分..--我想,唯一剩下的问题是:有没有更好的方法来优化我发布的查询?我希望能够像在SQL中使用“Count(1)和TotalCount”一样创建临时变量。似乎我只需要接受Linq,并希望它能做得很好,因为数据库调用依赖于查询和以后使用的混合。。有什么想法吗?@Gwar:我建议你试着去理解LINQ是如何工作的,因为你不必“仅仅希望它做得很好”。在单个数据库查询中执行
计数和主结果可能很困难,但是