我开始学习实体框架和asp.net,我想使用所有CRUD操作。 我有任务和类别模型,它们之间存在多对多关系。在我的数据库中,有3个表:1. 任务(包含ID,标题,描述..),2. 类别(包含categoryId和categoryName)和3。 TaskCategory (包含ID(任务ID)和类别ID)。
我设法完成了我想做的所有事情,只是使用下拉菜单为任务添加了多个类别。我创建了下拉列表,并加载了类别,并且我知道如何向任务中添加一个类别(关系为1:N时)(asp-for="CategoryId"
。对于多重选择,我尝试使用selectedCategories
(列出od整数-id)而不是CategoryId,但是我不知道如何处理该列表。在将任务保存到控制器中时如何在TaskCategory中加入类别和任务(换句话说:如何将类别保存到任务)?
AddTask.cshtml
<div class="form-group">
<label class="control-label">Category</label>
<select class="select-picker" asp-for="selectedCategories"
asp-items="@(new SelectList(Model.Categories, "CategoryId", "CategoryName"))" multiple>
</select>
</div>
<script>
...
$('.select-picker').selectpicker('toggle');
</script>
HomeController.cs
public IActionResult AddTask()
{
var categories = _categoryRepository.GetAllCategories().OrderBy(c => c.CategoryName);
var taskCategories = _taskCategoryRepository.GetAllTaskCategories().OrderBy(tc => tc.Id);
var homeViewModel = new HomeViewModel()
{
Task = null,
TaskCategory = null,
Categories = categories.ToList(),
TaskCategories = taskCategories.ToList(),
selectedCategories = new List<int>()
};
return View(homeViewModel);
}
[HttpPost]
public IActionResult AddTask(Task task, List<int> selected)
{
// foreach (var selectedCategoryId in selected)
// {
//
// }
_taskRepository.AddTask(task);
return RedirectToAction("Index");
return View();
}
通过这种方式,我可以在数据库中获取Task,但是当然不保存任何类别。
答案 0 :(得分:0)
尝试使用ViewModel处理关系,以下是我制作的工作演示,您可以根据需要参考并进行修改
任务与类别之间的多对多关系:
public class Task
{
public int Id { get; set; }
public string Title { get; set; }
public List<TaskCategory> TaskCategories { get; set; }
}
public class Category
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public List<TaskCategory> TaskCategories { get; set; }
}
public class TaskCategory
{
public int CategoryId { get; set; }
public Category Category { get; set; }
public int TaskId { get; set; }
public Task Task { get; set; }
}
//DbContext
public DbSet<Task> Task { get; set; }
public DbSet<Category> Category { get; set; }
public DbSet<TaskCategory> TaskCategory { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<TaskCategory>()
.HasKey(t => new { t.CategoryId, t.TaskId });
modelBuilder.Entity<TaskCategory>()
.HasOne(pt => pt.Category)
.WithMany(p => p.TaskCategories)
.HasForeignKey(pt => pt.CategoryId);
modelBuilder.Entity<TaskCategory>()
.HasOne(pt => pt.Task)
.WithMany(t => t.TaskCategories)
.HasForeignKey(pt => pt.TaskId);
}
创建一个TaskViewModel,一个元素回发其所选选项值的数组(在您的情况下,它将是一个类别Id
值的数组)。您的模型需要绑定属性。添加以下属性:
public class TaskViewModel
{
public Task Task { get; set; }
public SelectList CategoryList { get; set; }
public List<int> selectedCategories { get; set; }
}
AddTask.cshtml:
@model WebApplication1.Models.Tasks.TaskViewModel
<div class="row">
<div class="col-md-4">
<form asp-action="AddTask">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Task.Title" class="control-label"></label>
<input asp-for="Task.Title" class="form-control" />
<span asp-validation-for="Task.Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="selectedCategories" class="control-label"></label>
<select asp-for="selectedCategories" class="form-control" asp-items="Model.CategoryList" multiple></select>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</form>
</div>
</div>
然后在Post方法中,selectedCategories
的值将包含您在视图中选择的CategoryId
值的数组。
[HttpPost]
public IActionResult AddTask(TaskViewModel taskVM)
{
Models.Tasks.Task task = taskVM.Task;
_context.Add(task);
_context.SaveChanges();
foreach(var selectedId in taskVM.selectedCategories)
{
_context.TaskCategory.Add(new TaskCategory
{
TaskId = task.Id,
CategoryId = selectedId,
});
}
_context.SaveChanges();
return RedirectToAction("Index");
}