开发者

What is the behaviour when returning a query result through a function and then continuing to query on that result?

I am using ASP.NET MVC 3 with Entity Framework 4 using POCOs and want to query a set and select some properties to put into my viewModel. I will sketch a simplified version of my situation:

Situation:

I have an entity BananaTree containing a collection of Banana

public class Banana
{
    public int Id { get; set; }
    public int Size { get; set; }
    public TimeSpan Age { get; set }
    public string Description { get; set; }
}

public class BananaTree
{
    public int Id { get; set; }
    public ICollection<Banana> Bananas { get; set; }
}

I also have a view model BananaListItemViewModel used in the view showing a list of bananas for a certain banana tree. This view is managed by the BananaTreeController

public class BananaListItemViewModel
{
    public int Id { get; set; }
    public TimeSpan Age { get; set }
}

I have a Details action on the controller like so:

public ActionResult Details(int bananaTreeId)
{
    var viewModel = from bananaTree in bananaTreeRepository.BananaTrees
                    where bananaTree.Id == bananaTreeId
                    from banana in bananaTree.Bananas
                    select new BananaListItemViewModel
                    {
                        Id = banana.Id,
                        Age = banana.Age
                    };

    return View(viewModel);
}

What I want to change

This works fine and now I only select the items from the database that I need for my view model. However, I want to take out some more logic from my controller and am trying to do this as much as possible.

I would like to have a function in my repository like so:

IQueryable<Banana> GetBananas(int bananaTreeId)
{
    return (from bananaTree in BananaTrees
            where bananaTree.Id == bananaTreeId
            select bananaTree.Bananas).Single().AsQueryable();
}

and use it like so:

public ActionResult Details(int bananaTreeId)
{
    var viewModel = from banana in bananaTreeRepository.GetBananas(bananaTreeId)
                    select new BananaListItemViewModel
                    {
                        Id = banana.Id,
                        Age = banana.Age
                    };

    return View(viewModel);
}

Question

My question is, in this case, will the two queries be combined and go to the database in one go like in my first example or will this first get all the bananas from the tree completely out of the database and perform the second query on that list? I would prefer the first case. If not, could I rewrite the GetBananas query to get that behaviour (for example like the query below)?

IQueryable<Banana> GetBananas(int bananaTreeId)
{
    return from bananaTree in BananaTrees
           where bananaTree.Id == bananaTreeId
        开发者_如何学Python   from banana in bananaTree.Bananas
           select banana;
}

Thanks very much in advance.


In your specific case, it will be only one query, if the call to Single() doesn't lead to the query to be executed. Unfortunately, I couldn't find any info on whether it does or does not. The call to AsQueryable does not trigger the execution as long, as the Bananas property really is an IQueryable.
According to http://msdn.microsoft.com/en-us/library/bb156472.aspx, the call to Single doesn't execute your query.
Conclusion:
You code should result in only one query.

In general:
You can pass an IQueryable from one method to another without it being implicitly executed.
The following code will result in only one SQL statement executed at the end, when the call to ToList happens:

IQueryable<Banana> GetBananasByWeight(int weight)
{
    return from banana in Bananas where banana.Weight = weight;
}

IQueryable<Banana> FilterByQuality(IQueryable<Banana> bananaQuery, int quality)
{
    return bananaQuery.Where(b => b.Quality == quality);
}

public List<Banana> GetBananas(int weight, int quality)
{
    var query = GetBananasByWeight(weight);
    var filteredBananas = FilterByQuality(query, quality);
    return filteredBananas.ToList();
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜