为什么我的foreach不工作?

时间:2013-03-31 22:07:05

标签: c# asp.net-mvc entity-framework

我正在学习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工作正常....

2 个答案:

答案 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();