所以我最近开始检查ASP。. NET MVC3和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; }
}
现在的重点是Ingredient是一个半固定的表(只有业务用户可以添加配料,但这是另一回事),并且一个人可以输入他/她的数据和他/她最喜欢的配料。这一切都很好,但我想通过连接两张表来创建前10个食材,然后执行group by, order by, count和limit(例如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; }
标记为虚拟的,这样成分表就会惰性加载。另外,你应该把它叫做Ingredient,因为它不只是一个ID,它是一个被引用的实际的Ingredient。
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);
order和Take的组合还不够吗?