0

我正在返回从 RESTAURANT、CUISINE、CITY 和 STARRATING 表中提取信息的餐馆列表。我想获取每家餐厅及其相关城市和美食的列表,以及 STARRATING 表中的平均评分。到目前为止,这就是我所拥有的……在此先感谢。

   RestaurantsEntities db = new RestaurantsEntities();
public List<RESTAURANT> getRestaurantsWRating(string cuisineName, string cityName, string priceName, string ratingName)
{
    var cuisineID = db.CUISINEs.First(s => s.CUISINE_NAME == cuisineName).CUISINE_ID;
    List<RESTAURANT> result = (from RESTAURANT in db.RESTAURANTs.Include("CITY").Include("CUISINE").Include("STARRATING")
                               where RESTAURANT.CUISINE_ID == cuisineID
                               orderby RESTAURANT.REST_NAME ascending
                               select RESTAURANT).ToList();

    return result;
}
4

2 回答 2

0

从你所拥有的看起来Restaurant有一个STARRATING集合。如果是这样,您可以这样做:

from r in db.Restaurants
where r.CUISINE_ID == cuisineID
orderby r.REST_NAME ascending
select new { 
    Restaurant = r, 
    City = r.CITY,
    Cuisine = r.CUISINE,
    AvgRating = r.STARRATING.Average(rt => rt.Rating) 
}

如果这不正确,您需要提供有关您的类和关联的更多信息(最好是类图)。

(顺便说一句,对类和属性名称使用大写字母是不习惯的)。

于 2012-07-28T07:32:39.853 回答
-1

首先,我会将上面的整个代码块包装在 using 语句中:

using(RestaurantEntities db = new RestaurantEntities())
{
    ...
}

这将有助于清理 EF 上下文。

我通常会这样做的方式是,如果您可以控制您的数据库,我会在数据库中创建一个执行此工作的视图,将视图添加到您的实体模型并查询该视图。这简化了整个过程并将聚合的工作卸载到数据库中。

如果您无法控制数据库或不喜欢视图技术,那么我会像您所做的那样使用包含技术进行查询,然后将部分类添加到 RESTAURANT(如果使用模型优先)以添加AverageRating 属性,然后手动计算每个相关 STARRATING 组相关行的平均值,并将结果值应用于添加的属性。获得所有数据后,您可以通过 linq to objects 执行此操作。除非您确信只返回一个或几个 RESTAURANT 实例,否则此技术不会随着更多数据的累积而很好地扩展。你可以使用类似的东西:

//query data as you have done above...
foreach(RESTAURANT r in result)
{
    if(r.STARRATING.Count() > 0)
    {
        r.AverageRating = r.STARRATING.Average(rating => rating.Value); //.Value is your field name
    }
    else
    {
        r.AverageRating = 0; // or whatever default you prefer...
    }
}

希望这可以帮助。

于 2012-07-27T02:47:54.253 回答