Linq 通过函数返回查询结果,然后继续查询该结果时的行为是什么?
我使用的是ASP.NET MVC 3和实体框架4,使用的是POCOs,我想查询一个集合并选择一些属性放入我的viewModel。我将简略地描述我的情况: 情况: 我有一个实体Linq 通过函数返回查询结果,然后继续查询该结果时的行为是什么?,linq,asp.net-mvc-3,entity-framework-4,Linq,Asp.net Mvc 3,Entity Framework 4,我使用的是ASP.NET MVC 3和实体框架4,使用的是POCOs,我想查询一个集合并选择一些属性放入我的viewModel。我将简略地描述我的情况: 情况: 我有一个实体BananaTree,包含BananaTree public class Banana { public int Id { get; set; } public int Size { get; set; } public TimeSpan Age { get; set } public str
BananaTree
,包含BananaTree
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; }
}
我在控制器上有一个详细操作,如下所示:
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);
}
我想改变什么
这很好,现在我只从数据库中选择视图模型所需的项。然而,我想从我的控制器中拿出更多的逻辑,并尽可能多地这样做
我希望在我的存储库中有这样一个功能:
IQueryable<Banana> GetBananas(int bananaTreeId)
{
return (from bananaTree in BananaTrees
where bananaTree.Id == bananaTreeId
select bananaTree.Bananas).Single().AsQueryable();
}
问题:
我的问题是,在这种情况下,这两个查询是否会像我的第一个示例中那样合并并一次转到数据库,还是第一次将树中的所有香蕉完全从数据库中取出并对该列表执行第二次查询?我更喜欢第一种情况。如果没有,我是否可以重写getBanana
查询以获得该行为(例如,像下面的查询)
IQueryable GetBanana(int bananaTreeId)
{
从BananaTrees的bananaTree返回
其中bananaTree.Id==bananaTreeId
来自巴纳纳特里的香蕉。香蕉
选择香蕉;
}
非常感谢。在您的特定情况下,如果对
Single()
的调用没有导致执行查询,则只会执行一个查询。不幸的是,我找不到任何关于它是否存在的信息。只要Bananas
属性确实是IQueryable
,对AsQueryable
的调用就不会触发执行
根据,对Single
的调用不会执行您的查询。结论:
您的代码应该只产生一个查询 一般来说:
您可以将
IQueryable
从一个方法传递到另一个方法,而无需隐式执行它。当调用
ToList
时,以下代码只会在末尾执行一条SQL语句:
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();
}
IQueryable GetBananasByWeight(整数权重)
{
从香蕉中返回香蕉。重量=重量;
}
IQueryable FilterByQuality(IQueryable bananaQuery,int-quality)
{
返回bananaQuery.Where(b=>b.Quality==Quality);
}
公共列表(整数重量、整数质量)
{
var query=GetBananasByWeight(权重);
var filteredbanas=FilterByQuality(查询,质量);
返回filteredbanas.ToList();
}
single调用是避免IEnumerable的必要步骤。所以我收集了一些香蕉。单点指向“一个单一的bananaTree”。另外,我希望避免检索香蕉的所有属性。因此,我对函数的结果再次使用select。当发生ToList()
时,将执行两个查询,还是将它们合并为一个?这就是我所说的:它将只有一个。@Daniel:您将得到一个ICollection
,而不是IEnumerable
。所以不是一个香蕉,而是一棵树上的多个香蕉。@Matthijs:是的,我已经从你的第一句话中了解到了。我改变了答案,去掉了那个部分。
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);
}
IQueryable<Banana> GetBananas(int bananaTreeId)
{
return from bananaTree in BananaTrees
where bananaTree.Id == bananaTreeId
from banana in bananaTree.Bananas
select banana;
}
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();
}