C# Linq to Entities返回列表以及每个项目的平均评分

C# Linq to Entities返回列表以及每个项目的平均评分,c#,asp.net,linq-to-entities,aggregate-functions,C#,Asp.net,Linq To Entities,Aggregate Functions,我正在返回一份餐馆列表,从餐馆、菜肴、城市和星级表中获取信息。我想得到一份每个餐厅的列表,包括其相关的城市和菜肴,以及星级表中的平均等级。这就是我所拥有的,到目前为止。。。提前谢谢 RestaurantsEntities db = new RestaurantsEntities(); public List<RESTAURANT> getRestaurantsWRating(string cuisineName, string cityName, string priceNam

我正在返回一份餐馆列表,从餐馆、菜肴、城市和星级表中获取信息。我想得到一份每个餐厅的列表,包括其相关的城市和菜肴,以及星级表中的平均等级。这就是我所拥有的,到目前为止。。。提前谢谢

   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;
}
RestaurantEntities db=new RestaurantEntities();
公共列表getRestaurantsWRating(字符串cuisineName、字符串cityName、字符串priceName、字符串ratingName)
{
var cuisineID=db.CUISINEs.First(s=>s.CUISINEs\u NAME==cuisineName).cuisineID;
列表结果=(来自db餐厅中的餐厅。包括(“城市”)。包括(“美食”)。包括(“星级”)
where RESTAURANT.carcine\u ID==菜系ID
orderby RESTAURANT.REST\u名称升序
选择餐厅);
返回结果;
}

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

using(RestaurantEntities db = new RestaurantEntities())
{
    ...
}
这将有助于清理EF上下文

我通常会这样做,如果你控制了你的数据库,我会在数据库中创建一个视图来完成这项工作,将视图添加到你的实体模型中并查询视图。这简化了整个过程,并将聚合工作卸载到数据库中

如果您不能控制数据库或不喜欢视图技术,那么我将像您一样使用include技术进行查询,然后向RESTAURANT添加一个分部类(如果先使用model)为了添加AverageRating属性,然后手动计算相关行的每个相关星号集的平均值,并将结果值应用于添加的属性。您可以在收回所有数据后通过linq对对象执行此操作。除非您确信自己只返回一个或几个餐厅实例,否则此技术无法很好地扩展,因为会积累更多数据。您可以使用以下内容:

//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...
    }
}

希望这能有所帮助。

从您现有的来看,这家餐厅似乎有一个星光熠熠的系列。如果是这样,您可以这样做:

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) 
}
如果这不正确,您需要提供更多关于类和关联的信息(最好是类图)


(顺便说一句,在类和属性名中使用大写字母是不常见的)。

这种方法伸缩性不强,应该使用.GroupBy()完成。我提到过,它伸缩性不太好。视图方法是实现这一点的合理方法,而不必在linq查询中执行GroupBy()。我同意这是获取linq查询以返回适当结果的正确方法,但假设RESTAURANT类上没有接受结果的目标属性。