开发者

Get count from join table - EFCodeFirst

So I've recently began checking on ASP.NET MVC3 and EFCodeFirst and have gotten stuck. I have 2 Models: Person:

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

and Ingredient:

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

Now the point is that Ingredient is a semi-fixed table (only business users can add ingredients, but that's a different story) and a person can input his/her data and his/her favorite ingredient. This all works fine but I wanted to create a top 10 of ingredients by joining the 2 tables开发者_运维技巧, and then performing a group by, order by, count and limit (to 10 for example).

The issue here is that I've tried several things and just can't get it to work. I'm quite new to LINQ and can't get my head on how to do this.

Any suggestions would be greatly appreciated!

Edit: To specify once more, I just need the equivalent of the following query in 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;


You should mark the public Ingredient IngredientID { get; set; } as virtual, this way the ingredient table is loaded lazily. Also you should just call it Ingredient since it's not just the ID, it's an actual Ingredient that is referenced.

If i understand you correctly you want to figure out which ingredient is the most popular? If so just group the persons by Ingredient.IngredientID and count the amount of persons in each grouping.

Another way of doing is to add a

public virtual ICollection<Person> Persons { get; set;} field to the Ingredient class, now you can just do

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

This gives you a dictionary with each ingredient name as key and the count as value, ordered in descending order by count. If you get a ArgumentException it's because you have multiple ingredients with the same name:

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


Combination of OrderBy and Take is not enough?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜