通过linq显示数据

时间:2019-04-14 18:03:46

标签: c# entity-framework linq

我想显示特定分级的食物信息。

List<Rating> rates = db.Ratings.OrderByDescending(e => e.Rate).ToList();                    
int i = 0;
foreach(Rating rate in rates)
{
    rates[i].Food = db.Foods.Where(e => e.ID == rate.FID).FirstOrDefault();
    i++;
}
return Request.HttpCreateResponse(rates);

上面的代码显示了此信息,但我只希望以该价格作为食物对象。

"rate": [
        {
            "ID": 15,
            "Rate": 5,
            "FID": 65,
            "UID": 102,
            "Food": {
                "ID": 65,
                "Name": "Grilled chicken",
                "Price": "580",
                "CatID": 75,
                "UID": 101,
                "Date_Time": "2019-04-01T00:00:00",
                "FoodDescription": "Chicken with some oregeno",
                "CookingTime": "25 min",
                "Image": "",
                "Uploadedby": "Hanzala Iqbal",
                "Carts": [],
                "Category": null,
                "User": null,
                "FoodRecommendations": [],
                "OrderFoods": [],
                "Ratings": []
            },

我想要这样。

{
    "ID": 65,
    "Name": "Grilled chicken",
    "Price": "580",
    "CatID": 75,
    "UID": 101,
    "Date_Time": "2019-04-01T00:00:00",
    "FoodDescription": "Chicken with some oregeno",
    "CookingTime": "25 min",
    "Image": "",
    "Uploadedby": "Hanzala Iqbal",
    "Carts": [],
    "Category": null,
    "User": null,
    "FoodRecommendations": [],
    "OrderFoods": [],
    "Ratings": []
},

希望您提前了解我要实现的目标。

1 个答案:

答案 0 :(得分:1)

基于rates[i].Food = ...,您的评级实体已经与食品建立了关系。您的代码正在做一些不必要的事情:

  1. 选择N + 1:通过遍历已检索的评级,您将再次进入数据库以获取每个食物。这意味着1条查询可读取200个评分,而200条查询可一次读取食品的1个评分。
  2. 当您不想更新实体时设置实体引用:这是一种不好的做法,因为如果DbContext范围内的更高版本代码调用SaveChanges,您将遇到FK错误或数据正在更新,打算。
  3. 返回的实体和错误的实体:您不想返回Ratings,而是想要返回Food。您还应该避免从调用返回Entity对象,因为这通常包含太多有关您的架构的信息,并且您应该从不接受客户端代码中的实体以执行诸如附加到上下文和SaveChanges之类的操作。感觉很方便,并且意味着更少的编码,但会使您的系统遭受各种意外/意外更新。

要获得所需的食物,您只需要利用评分与食物之间的关系,将相关数据选择到ViewModel中,然后返回视图模型即可。

ViewModel:

[Serializable]
public class FoodViewModel
{
    public int ID {get; set}
    public string Name {get; set}
    public decimal Price {get; set}
    public DateTime Date_Time" {get; set}
    public string FoodDescription {get; set}
    public string CookingTime {get; set}
    public string Uploadedby {get; set}
}

如果您确实需要返回详细信息的集合(购物车,FoodRecommendations等),则可以为它们定义视图模型。通常,只需返回视图/消费者所需的数据即可。

要通过降级选择食物:

var foodViewModels = db.Ratings.OrderByDescending(e => e.Rate)
    .Select(e => new FoodViewModel
    {
        ID = e.Food.ID,
        Name = e.Food.Name,
        Price = e.Food.Price,
        DateTime Date_Time = e.Food.Date_Time,
        FoodDescription = e.Food.FoodDescription,
        CookingTime = e.Food.CookingTime,
        UploadedBy = e.Food.UploadedBy
    }).Distinct().ToList();

return Request.HttpCreateResponse(foodViewModels);

猜测,食物与等级之间的关系似乎是多对一的关系,其中每种食物可能具有多个等级,因此您可能需要限制结果以仅按其最大等级列出食物。在.Distinct()之前,.ToList()可能就足够了,或者从db.Foods中选择食物并按.Max(f => Rating.Rate)

进行排序

即:

var foodViewModels = db.Foods.OrderByDescending(f => f.Ratings.Max(r => r.Rate))
    .Select(f => new FoodViewModel
    {
        ID = f.ID,
        Name = f.Name,
        Price = f.Price,
        DateTime Date_Time = f.Date_Time,
        FoodDescription = f.FoodDescription,
        CookingTime = f.CookingTime,
        UploadedBy = f.UploadedBy
    }).ToList();