从连接表中获取计数 - EFCodeFirst

问题描述:

所以我最近开始检查ASP.NET MVC3和EFCodeFirst并且陷入了困境。 我有2种型号: 人:从连接表中获取计数 - EFCodeFirst

[Bind(Exclude = "PersonID")] 
    public class Person { 

     public int PersonID { get; set; } 

     [Required(ErrorMessage="Given name is a required field")] 
     [DisplayName("Given name")] 
     public string GivenName { get; set; } 

     [Required(ErrorMessage="Family name is a required field")] 
     [DisplayName("family name")] 
     public string FamilyName { get; set; } 

     [Required(ErrorMessage = "Birthdate is a required field")] 
     [DisplayFormat(DataFormatString = "{0:d}")] 
     public DateTime Birthdate { get; set; } 

     [DisplayName("Ingredient")] 
     public virtual Ingredient Ingredient { get; set; } 
} 

和配料:

public class Ingredient { 
    public int IngredientID { get; set; } 

    [Required(ErrorMessage = "Ingredient is a required field")] 
    public string Name { get; set; } 

    public virtual ICollection<Person> Persons { get; set; } 
} 

现在问题是,成分是半固定表(仅企业用户可以添加的成分,但是这是一个不同的故事),并且一个人可以输入他/她的数据和他/她最喜欢的成分。 这一切都正常,但我想通过加入2个表格,然后按顺序,计数和限制(以10为例)创建一个前10个成分。

这里的问题是,我已经尝试了几件事情,只是不能得到它的工作。我对LINQ相当陌生,无法理解如何做到这一点。

任何建议将不胜感激!

编辑: 要指定一次,我只需要下面的查询在LINQ相当于:

SELECT i.name, COUNT(p.Ingredient_IngredientID) AS Total 
FROM People p, Ingredients i 
WHERE p.Ingredient_IngredientID = i.IngredientID 
GROUP BY i.name 
ORDER BY total DESC; 

你应该标记public Ingredient IngredientID { get; set; }虚拟,这样的成分表延迟加载。你也应该把它称为配料,因为它不仅仅是ID,它是一个被引用的实际成分。

如果我正确理解你,你想弄清楚哪种成分是最受欢迎的?如果是这样,只需按照Ingredient.IredredID将人员分组并计算每个分组中的人员数量。

做的另一种方式是一个

public virtual ICollection<Person> Persons { get; set;}字段添加到配料类,现在你可以做

var tenMostPopularIngredients = (from i in Ingredients 
          orderby i.Persons.Count() descending 
          select i).Take(10); 

这为您提供了每种成分的名称为键和计数作为字典值,按数量降序排列。如果你得到一个ArgumentException的,那是因为你有多个同名的成分:

var tenMostPopularIngredients = (from i in ingredients 
           let count = i.Persons.Count() 
           orderby count descending 
           select new 
           { 
            Ingredient = i, 
            Count = count 
           } 
           ).Take(10).ToDictionary(t => t.Ingredient.Name,t => t.Count); 
+0

+1我没有注意到他没有说明从Ingredient到Person的导航。 – Euphoric 2011-04-17 16:58:38

+0

正是我想要的,谢谢! – Fverswijver 2011-04-17 17:39:10

+0

说得太快,显然它*有点*的作品,但只是给了我一份重复每一种成分的清单。即: - 番茄 - 沙拉 - 苹果 - 番茄 – Fverswijver 2011-04-18 19:52:11

OrderByTake组合是不够的?