2

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

4

2 回答 2

4

您需要了解 Linq 和 EF 如何协同工作:
EF 不会获取所有实体,然后在代码中执行约束,但它会将“所有内容”转换为 SQL,而对于不支持的属性/方法则无法做到这一点存在于您的数据库中。

您可以执行以下操作之一:

1)首先获取所有实体,然后“在代码中”执行排序:

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)创建一个“帮助列/表”,在其中插入“排序/排序值”并在其后排序。

方法一的缺点是,与您匹配的所有实体Where()都已加载,而不仅是 3,方法 2 我不确定它是否有效,方法 3 需要八个数据库触发器或通过代码手动更新,两者都可能对性能不利。

于 2013-03-31T22:11:37.833 回答
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();
于 2013-03-31T22:09:41.917 回答