在MVC控制器中使用EF进行多对多的实现

时间:2023-02-02 00:15:23

I have an app where I have Recipes and Tags. Since Recipes can have multiple Tags, and Tags can belong to multiple recipes, I have the following models:

我有一个应用程序,我有食谱和标签。由于食谱可以有多个标签,而标签可以属于多个食谱,我有以下模型:

public class Tag : IModel
{
    [Key]
    public int ID { get; set; }
    [Required(ErrorMessage = "Name is required.")]
    public string Name { get; set; }
    public virtual ICollection<Recipe> Recipes { get;set; }
}

public class Recipe : IModel
{
    [Key]
    public int ID { get; set; }
    [ForeignKey("Category")]
    public int CategoryId { get; set; }
    [Required(ErrorMessage = "The Title is required.")]
    public string Title { get; set; }
    public virtual ICollection<Tag> Tags { get; set; }
    public virtual Category Category { get; set; }
}

My Recipe controller has a an HttpGet Edit action that returns a recipe for the view:

我的Recipe控制器有一个HttpGet Edit操作,它返回视图的配方:

public ActionResult Edit(int id = 0)
    {

        Recipe recipe = _recipeService.GetByID(id, "Category,Tags");
        if (recipe == null)
        {
            return HttpNotFound();
        }
        CreateEditRecipeViewModel viewModel = new CreateEditRecipeViewModel(recipe, PopulateCategoryLookup(recipe));
        return View(viewModel);
    }

At this point, the Recipe's Tag collection is populated by my GetById() method. However, I'm unclear about how I am supposed to add a collection to the view model so that it could be surfaced in the View. Here is my current viewmodel:

此时,Recipe的Tag集合由我的GetById()方法填充。但是,我不清楚我应该如何向视图模型添加一个集合,以便它可以在视图中浮出水面。这是我当前的viewmodel:

public class CreateEditRecipeViewModel
{        
    [HiddenInput]
    public int RecipeID { get; set; }
    public int CategoryId { get; set; }
    [Required(ErrorMessage = "The Title is required.")]
    public string Title { get; set; }
}

In my view, I would like to have a textbox where I would have a comma separated list of Tags (e.g. breakfast, vegatarian, gluten-free). When the Edit view is brought up, I would like it populated with the name of each Tag currently assigned to the recipe. When the form is posted, I would like to split the Tag list up, and in the HttpPost Edit action, reconcile the values with EF.

在我看来,我希望有一个文本框,我可以用逗号分隔的标签列表(例如早餐,蔬菜,无麸质)。启动编辑视图时,我希望它填充当前分配给配方的每个标记的名称。发布表单时,我想将标记列表拆分,然后在HttpPost编辑操作中,将值与EF进行协调。

If anyone has guidance on representing a collection of complex objects in a ViewModel and a View, I'd appreciate it!

如果有人有关于在ViewModel和View中表示复杂对象集合的指导,我会很感激!

Thanks,

谢谢,

Chris

克里斯

1 个解决方案

#1


1  

I usually use the ListBoxFor tag combined with the Chosen jquery plugin to do multiselect. Amazingly straightforward. I'll make a go at how this should look code wise. But I don't have VS at hand to test. Something like:

我通常使用ListBoxFor标签与Chosen jquery插件结合进行多选。非常直截了当。我会详细说明这应该是代码明智的。但是我手头没有VS来测试。就像是:

public class CreateEditRecipeViewModel
{        
    [HiddenInput]
    public int RecipeID { get; set; }
    public int CategoryId { get; set; }
    public List<int> TagIds { get; set; }
    [Required(ErrorMessage = "The Title is required.")]
    public string Title { get; set; }
}

//Then in view...

@Html.ListBoxFor(model => model.TagIds, HelperMethodToGetSelectListOfTags())

Then like you mentioned you would just reconcile the selected id's with EF when you turn your view model back into a regular model.

然后就像你提到的那样,当您将视图模型转换回常规模型时,您只需将选定的ID与EF进行协调。

The only drawback to this approach is you would need some separate code for creating new tags. But you didn't mention that as a requirement.

这种方法的唯一缺点是您需要一些单独的代码来创建新标签。但你没有提到这是一个要求。

Hope that helps!

希望有所帮助!

#1


1  

I usually use the ListBoxFor tag combined with the Chosen jquery plugin to do multiselect. Amazingly straightforward. I'll make a go at how this should look code wise. But I don't have VS at hand to test. Something like:

我通常使用ListBoxFor标签与Chosen jquery插件结合进行多选。非常直截了当。我会详细说明这应该是代码明智的。但是我手头没有VS来测试。就像是:

public class CreateEditRecipeViewModel
{        
    [HiddenInput]
    public int RecipeID { get; set; }
    public int CategoryId { get; set; }
    public List<int> TagIds { get; set; }
    [Required(ErrorMessage = "The Title is required.")]
    public string Title { get; set; }
}

//Then in view...

@Html.ListBoxFor(model => model.TagIds, HelperMethodToGetSelectListOfTags())

Then like you mentioned you would just reconcile the selected id's with EF when you turn your view model back into a regular model.

然后就像你提到的那样,当您将视图模型转换回常规模型时,您只需将选定的ID与EF进行协调。

The only drawback to this approach is you would need some separate code for creating new tags. But you didn't mention that as a requirement.

这种方法的唯一缺点是您需要一些单独的代码来创建新标签。但你没有提到这是一个要求。

Hope that helps!

希望有所帮助!