基于表值中的非null查询附加表并返回视图

时间:2015-04-15 17:37:20

标签: c# asp.net-mvc entity-framework model

我正在尝试编写存储食谱的应用程序。然而,一些成分也可以是“食谱”。我现在所困扰的是如何为具有多种可能的不同较小食谱的食物提供完整的成分列表。对不起,这有点长。以下是模型:

public class Recipe
{

    public int RecipeID { get; set; }
    public string Recipe_Name { get; set; }
    public int Labor_Cost { get; set; }

    public virtual ICollection<RecipeDetail> RecipeDetails { get; set; }

}

public class RecipeDetail
{
    public int RecipeDetailID {get; set;}
    public int RecipeID { get; set; }
    public int IngrediantID { get; set; }
    public int Quantity { get; set; }

    public virtual Recipe Recipe { get; set; }
    public virtual Ingrediant Ingrediant { get; set; }

}

public class Ingrediant
{

    public int IngrediantID { get; set; }
    public string Ingrediant_Name { get; set; } 
    public bool? BreaksDown { get; set; }
    public int? RecipeID { get; set; }  

    public virtual AHItem AHItems { get; set; }

}

所以这就是我的想法,并认为它会起作用,但我觉得它是非常正确的。我的第一个想法是将整个链接数据库传递给视图,然后从那里拉出我需要的东西。

所以控制器看起来像这样:(只是将所有内容发送到视图)。

public ActionResult Details(int? id)
{
    if (id == null)
    {
       return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }

    ViewBag.SelectedDetail = id;

    Recipe recipe = db.Recipes;
    if (recipe == null)
    {
        return HttpNotFound();
    }

        return View(recipe);
}

然后所有的过滤都会在视图中发生......有点像这样(是的,这是丑陋的,它会创建错误的表结构,一旦我弄明白,我就会修复它)。

@foreach (var item in Model.RecipeDetails)
{
    if (item.RecipeID == ViewBag.SelectedDetail)
    {
        if (item.Ingrediant.AHItems != null)
        {
            x = x + item.Ingrediant.AHItems.Cost;
        }
          <tr>
            <td>
              @Html.DisplayFor(modelItem => item.Ingrediant.Ingrediant_Name)
            </td>
            <td>
              @Html.DisplayFor(modelItem => item.Quantity)
            </td>
            <td>
              @Html.DisplayFor(modelItem => item.Ingrediant.AHItems.Cost)
            </td>
         </tr>

    if (item.Ingrediant.RecipeID != null)
    {
        y= item.Ingrediant.RecipeID;
        foreach (var i in Model.RecipeDetails)
        {
           if (item.RecipeID == y)
           {
             <tr>
                <th>Item Name</th>
                <th>Amount Needed</th>
                <th>AH Cost</th>
             </tr>
             <tr>
               <td>
                    @Html.DisplayFor(modelItem => i.Ingrediant.Ingrediant_Name)
               </td>
               <td>
                    @Html.DisplayFor(modelItem => i.Quantity)
               </td>
               <td>
                    @Html.DisplayFor(modelItem => i.Ingrediant.AHItems.Cost)
               </td>
             </tr>
            }

                        }
                    }
                }
            }

因此,虽然我认为我可以完成上述工作,但似乎在视图中需要做很多额外的工作。我如何将其移入控制器?

P.S。当“recipe”传递给视图而不必编写某些东西来查看它时,有没有办法看到模型将为上面的示例制作的完整链接表?我想看看连接(以及如何编写查询),这样我就可以更好地理解它在做什么。

1 个答案:

答案 0 :(得分:0)

将所有食谱传递到仅显示一个的视图根本不是一个好主意。获得您需要的食谱:

var recipe = db.Recipes.Find(id);
if (recipe == null)
{
    return new HttpNotFoundResult();
}

但是,由于您在视图中也有相关的实体,因此您应该稍微修改一下:

var recipe = db.Recipes.Include("RecipeDetail.Recipe").Include("RecipeDetail.Ingredient").SingleOrDefault(m => m.Id == id);

这将为RecipeDetail发出加入,并加入Recipe上的Ingredient和/或RecipeDetail属性。结果将是基于id的单个Recipe实例,其中包含急切加载的所有相关RecipeDetail个实例以及RecipeIngredient相关的信息每个RecipeDetail。您的视图现在具有单个查询所需的所有信息,您无需将数据库转储到视图中即可。