从连接表中获取计数 - EFCodeFirst

时间:2011-04-17 16:29:47

标签: c# .net asp.net linq asp.net-mvc-3

所以我最近开始检查ASP.NET MVC3和EFCodeFirst并且已经卡住了。 我有2个型号: 人:

    [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;

2 个答案:

答案 0 :(得分:3)

你应该将public Ingredient IngredientID { get; set; }标记为虚拟,这样就可以懒惰地加载成分表。你也应该称它为Ingredient,因为它不仅仅是ID,它是一个实际的成分被引用。

如果我理解你,你想知道哪种成分最受欢迎?如果是这样,只需按Ingredient.IngredientID对人员进行分组,并计算每个分组中的人数。

另一种方法是添加

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

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);

答案 1 :(得分:0)

OrderByTake的组合是不够的?