views:

104

answers:

3

Hi,

Can anyone tell me if the following query calls the database multiple times or just once?

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

I really need to get the Count() out of the query and I couldn't find another way to do it so if you have some better optimized code, feel free to share it!

Thanks in advance!

Gwar

A: 

This will definitely result in two calls.

Ronald Wildenberg
A: 

You should check out Scott Guthrie's post on using the LINQ to SQL Debug Visualizer. This will allow you to see exactly the SQL that will be generated from your LINQ statement.

sgriffinusa
+1  A: 

It totally depends on what you are doing with the bizItems variable, because after you've ran just this code, only a COUNT(*) query will have ran. This is because the item contains an IQueryable which is a description of a query (an intent to run), not the result of the operation. The query will only run when you start iterating this query, by using foreach or an operator such as .Count(). Besides this, the BusinessProfile and Products properties will probably also contain IQueryables.

So, let's take a look at what you might do with this code:

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

So, if you ask me again, looking at this code, how many queries will be sent to the database, my answer is: 2 + 2 * the number of items in bizItems.items. So the number of queries will be between 2 and (2 + 2 * pageSize).

Steven
Steven,That's a very informative answer. I wasn't aware of how much the query was being optimized, even after the fact. So basically, if I understand your reply correctly, there's no way to know how many calls will be made to the database unless you know exactly how the (intended) results are being used..Thanks!
Gwar
Had to split my comment in 2..----I guess, the only remaining question is: is there a better way to optimize the query I posted? I would love to be able to create temporary variables the same way 'Count(1) as TotalCount' works in SQL. It kind of seems like I just need to embrace Linq and just hope that it does a good job since database calls depend on a mix of query and later use.. Any thoughts?
Gwar
@Gwar: I advice you to try to understand how LINQ works, because you won't have to "just hope that it does a good job". It is probably hard to try to have the `Count` and main result execute in a single database query, however, it is possible to prevent all those 'sub' queries to execute by using anonymous types and the optimizations that LINQ to Entities offers.
Steven
@Gwar: If you find performance too slow, and can't manage to optimize it, post a new question with the query and the usage here on SO. Possibly also include the output of the `DataContext.Log` to your questions. If you formulate your question well, there will be enough people to help you.
Steven