2016-04-28 44 views
1

我正在处理一个配方管理器程序,首先使用Entity Framework 6代码。我有以下实体在数据库:LINQ表达式组合/加入

public class Item { 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity), Key]   
    public int ItemId { get; set; } 

    [Required] 
    public string ItemName {get; set; } 

    // Other properties 
} 

public class Recipe { 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity), Key] 
    public int RecipeId { get; set; } 

    [Required] 
    public string RecipeName { get; set; } 

    public virtual ICollection<Ingredient> Ingredients { get; set; } 

    // Other properties 
} 

public class Ingredient { 
    [Key, Column(Order = 0)] 
    public int RecipeId { get; set; } 

    [ForeignKey("RecipeId")] 
    public virtual Recipe Recipe { get; set; } 

    [Key, Column(Order = 1)] 
    public int ItemId { get; set; } 

    [ForeignKey("ItemId")] 
    public virtual Item Item { get; set; } 

    public double Quantity { get; set; } 

    // Other properties 
} 

public class Meal { 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity), Key]   
    public int MealId { get; set; } 

    [Required] 
    public string MealName {get; set; } 

    public virtual ICollection<Recipe> Recipes { get; set; } 

    public virtual IEnumerable<Ingredient> Ingredients() { 
     if (Recipes == null) 
      yield break; 

     foreach (var recipe in Recipes) 
      foreach (var ingredient in recipe.Ingredients) 
       yield return ingredient; 
    } 
} 

我的问题是在Meal类的Ingredients属性。那里的代码将返回制作膳食所需的所有配料列表,但我想返回一个组合列表。也就是说,如果餐中的一个配方需要2个鸡蛋,而另一个需要1个鸡蛋,则会返回两个鸡蛋入口。我想返回一个3个鸡蛋的入口。

有没有可用于组合这些的LINQ表达式?东西等同于:

SELECT item.ItemName, SUM(ing.Quantity) 
FROM Meals AS m 
JOIN RecipeMeals AS rm ON m.MealId = rm.Meal_MealId 
JOIN Ingredients AS ing ON rm.Recipe_RecipeId = ing.RecipeId 
JOIN Items AS item ON ing.ItemId = item.ItemId 
GROUP BY item.ItemName 

回答

0

当你定义导航属性(你确实有他们),它很容易 - 无需思考的加入,只是“导航“就好像它们是对象一样。 EF将为您生成必要的SQL连接。

等效的LINQ to Entities查询是这样的:

from meal in db.Meals 
from recipe in meal.Recipes 
from ingredient in recipe.Ingredients 
let item = ingredient.Item 
group ingredient by item.ItemName into itemGroup 
select new { ItemName = itemGroup.Key, Quantity = itemGroup.Sum(e => e.Quantity) } 
0

试试这个

var result = from m in Meals 
    join rm in RecipeMeals on m.MealId equals rm.Meal_MealId 
    join ing in Ingredients on rm.Recipe_RecipeId equals ing.RecipeId 
    join item in Items on ing.ItemId equals item.ItemId 
    group ing by item.ItemName into g 
    select new { g.Key, g.Sum(p => p.Quantity) } 
+0

这是行不通的。实体模型没有用于“RecipeMeals”表的实体。 –

+0

你是什么意思,'实体模型没有用于RecipeMeals表的实体'?你不能添加它吗?我在这里发布的是你的SQL查询到Linq的确切转换。 – schlonzo

+0

我首先使用实体​​框架代码。我在第一个列表中创建了类,然后添加了一个从'DbContext'降序的类来构建实体模型。模型中没有任何类用于多对多关系表。相反,有导航属性。 –