我正在学习asp.net mvc,我正在尝试制作类似Yelp的东西......
在我的一段代码中,我想迭代所有类别......
它从第2开始:我在foreach中遇到问题,它没有工作......
VStudio告诉我问题是属性AverageReviews属于Place类的属性:
public double AverageReviews
{ get { return (double)SumReviews/(Reviews.Count); } }
在我的控制器中我有这个:
private KekantoContext db = new KekantoContext();
for (int i = 2; i < 8; i++)
{
var query = db.Places.Where(e => e.Category.CategoryId == i)
.OrderByDescending(e => e.AverageReviews).Take(3);
foreach (var aux in query)
{
//any code }
}
}
Visual Studio说Linq to Entities不支持我的AverageReviews属性。但是,如果我更改代码并放入:var query = db.Places,我的foreach工作正常....
答案 0 :(得分:4)
您需要了解Linq和EF如何协同工作:
EF不会获取所有的entites,然后在代码中执行约束,但它会翻译&#34;所有内容&#34;到SQL,它不能用于数据库中不存在的属性/方法。
您可以执行以下操作之一:
1)首先获取所有实体,然后在代码&#34;中执行排序&#34;
var query = db.Places.Where(e => e.Category.CategoryId == i).ToList()
.OrderByDescending(e => e.AverageReviews).Take(3);
注意添加的ToList()
。
2)以EF可以理解的方式执行您的订购,即使您的逻辑可能也不容易,但可能类似以下工作:
var query = db.Places.Where(e => e.Category.CategoryId == i).
.OrderByDescending(e => e.SumReviews/e.Reviews.Count()).Take(3);
3)创建一个&#34;帮助列/表&#34;在哪里插入&#34; sort- / order-value&#34;然后订购。
方法一的缺点是,所有与Where()
匹配的实体都被加载,而不仅仅是3,方法2如果它甚至可以工作,我就不是真的,方法3需要更多的数据库触发器或通过代码更新manuel ,两者都可能对表现不利。
答案 1 :(得分:3)
AverateReviews
是一个计算属性,因此EF无法基于它生成商店查询(sql)。
您可以先检索数据,然后在其上调用ToList()
,然后按AverageReviews进行排序。
var query = db.Places.Where(e => e.Category.CategoryId == i).Take(3).ToList();
var orderedList = query.OrderByDescending(x => x.AverageReviews).ToList();
如果您想订购整个清单并取3个..请参阅下文。
var query = db.Places.Where(e => e.Category.CategoryId == i).ToList();
var orderedList = query.OrderByDescending(x => x.AverageReviews).Take(3).ToList();