简体   繁体   English

ASP.NET CORE 3.1 中通过存储库模式的多对多关系

[英]Many to Many relationship in ASP.NET CORE 3.1 by repository pattern

I've made many to many relationship in ASP.NET Core and there are two tables Category and Subject This is Category Model我在 ASP.NET Core 中建立了多对多关系,并且有两个表CategorySubject This is Category Model

public class Category
{
    [Key]
    public int Id { get; set; }

    public string  Name { get; set; }

    public List<CategorySubject> CategorySubjects { get; set; } = new List<CategorySubject>();
   
}

This is subject model这是主题模型

 public class Subject
{
    [Key]
    public int Id { get; set; }

    public string Name { get; set; }

    public string Exam_Time { get; set; }

    public List<CategorySubject> CategorySubjects { get; set; }
}

This is CategorySubject Model这是类别主题模型

public class CategorySubject
{
    public  int CategoryId { get; set; }

    public int  SubjectId { get; set; }

    public Category Category { get; set; }

    public Subject Subject { get; set; }
}

This is part of DatabaseContext这是 DatabaseContext 的一部分

public DbSet<CategorySubject> CategorySubjects { get; set; }
  protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<CategorySubject>().HasKey(pt => new { pt.CategoryId, pt.SubjectId });
        modelBuilder.Entity<CategorySubject>().HasOne(pt => pt.Category)
            .WithMany(pt => pt.CategorySubjects).HasForeignKey(p => p.CategoryId);

        modelBuilder.Entity<CategorySubject>().HasOne(pt => pt.Subject)
          .WithMany(pt => pt.CategorySubjects).HasForeignKey(p => p.SubjectId);
    }

I made one helper class by the name of Helper我用Helper的名字做了一个助手类

 public class Helpers:Profile
{
    public Helpers()
    {
        CreateMap<Subject, SubjectViewModel>().ReverseMap();
        CreateMap<SubjectViewModel, Subject>();
        CreateMap<Category, CategoryViewModel>().ReverseMap();
    }
}

this is category service:这是类别服务:

 public void Insert(Category category)
    {
        _context.Categories.Add(category);
    }

    public void Update(Category category)
    {
        _context.Categories.Update(category);
    }

This is CategoryController :这是CategoryController

// GET: CategoryController/Create
    public IActionResult Create()
    {

        var subjectFromRepo = _categorySubject.Subject.GetAll();
        var selectList = new List<SelectListItem>();
        foreach (var item in subjectFromRepo)
        {
            selectList.Add(new SelectListItem(item.Name, item.Id.ToString()));
        }

        var vm = new CategoryViewModel()
        {
            Subjects = selectList
        };

        return View(vm);
    }

   
 // POST: CategoryController/Create
    [HttpPost]
    [ValidateAntiForgeryToken]
    public IActionResult Create(CategoryViewModel vm )
    {
        try
        {
            Category category = new Category()
            {
                Name = vm.Name
                
            };
            foreach(var item in vm.SelectedSubjects)
            {
                category.CategorySubjects.Add(new CategorySubject()
                {
                    SubjectId = Int32.Parse(item)
                }); 
            }
            _categorySubject.Category.Insert(category);
            _categorySubject.Save();
            return RedirectToAction(nameof(Index));


            
        }
        catch
        {
            return View();
        }
    }

    // GET: CategoryController/Edit/5
    public IActionResult Edit(int id)
    {
        var category = _categorySubject.Category.GetCategoryById(id);
        var subjects = _categorySubject.Subject.GetAll();
        var selectsubjects = category.CategorySubjects.Select(x => new Subject()
        {
            Id = x.Subject.Id,
            Name = x.Subject.Name
        });

        var selectlist = new List<SelectListItem>();
        subjects.ForEach(i => selectlist.Add(new SelectListItem(i.Name, i.Id.ToString(), 
            selectsubjects.Select(x => x.Id).Contains(i.Id))));

        var vm = new CategoryViewModel()
        {
            Id= category.Id,
            Name = category.Name,
            Subjects = selectlist
        };
        return View(vm);
    }

    // POST: CategoryController/Edit/5
    [HttpPost]
    [ValidateAntiForgeryToken]
    public IActionResult Edit(CategoryViewModel vm)
    {
        try
        {
            var category = _categorySubject.Category.GetCategoryById(vm.Id);
            category.Name = vm.Name;
            var selectedSubjects = vm.SelectedSubjects;
            var existingSubjects = category.CategorySubjects.Select(x => x.SubjectId.ToString()).ToList();
            var toAdd = selectedSubjects.Except(existingSubjects).ToList();
            var toRemove = existingSubjects.Except(selectedSubjects).ToList();
            var CategorySubjects = category.CategorySubjects.Where(x => !toRemove.Contains(x.SubjectId.ToString())).ToList();
            foreach (var item in toAdd)
            {
                category.CategorySubjects.Add(new CategorySubject()
                {
                    SubjectId = Int32.Parse(item),
                    CategoryId = Int32.Parse(item)
                });
            }
            _categorySubject.Save();
            return RedirectToAction("Index", "Category");
        }
        catch
        {
            return View();
        }
    }

This is Create.cshtml of Category :这是Category Create.cshtml

<div class="style-form">
    <h2 class="text-center mt-3 mb-lg-3">Create New Category</h2>
    <form asp-action="Create">
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <div class="row">
            <div class="col-md-3 col-lg-3 col-sm-3"></div>
            <div class="col-md-6 col-lg-6 col-sm-6">
                <div class="input-group">
                    <div class="input-group-prepend">
                        <span class="input-group-text"><strong>Name:</strong></span>
                    </div>
                    <input asp-for="Name" class="form-control input-hover" placeholder="Enter Name.." />
                    <span asp-validation-for="Name" class="text-danger"></span>
                </div><br />
                <div class="input-group">
                    <div class="input-group-prepend">
                        <span class="input-group-text"><strong>Subject:</strong></span>
                    </div>
                    <select asp-for="SubjectId" class="form-control input-hover" asp-items="@Model.Subjects ">
                        <option value="">Please choose a Subject...</option>
                    </select>
                    <span asp-validation-for="SubjectId" class="text-danger"></span>
                </div><br />
            </div>
        </div>
        <div class="row">
            <div class="col-md-3 col-lg-3 col-sm-3"></div>
            <div class="col-md-6 col-lg-6 col-sm-6">
                <div class="form-group">
                    <button type="button" class="btn btn-backToList">
                        <a asp-action="Index">Back to List</a>
                    </button>
                    <button type="submit" class="btn btn-create">Create</button>
                </div>
                </div>
            </div>
         </form>

There when I click on the create new category button I can get data of subject form drop down list, but when I want to submit it I face this error:当我点击创建新类别按钮时,我可以获得主题表单下拉列表的数据,但是当我想提交它时,我遇到了这个错误:

NullReferenceException: Object reference not set to an instance of an object. NullReferenceException:未将对象引用设置为对象的实例。 AspNetCore.Views_Category_Create.b__20_0() in Create.cshtml, line 27 Create.cshtml 中的 AspNetCore.Views_Category_Create.b__20_0(),第 27 行

<select asp-for="SubjectId" class="form-control input-hover" asp-items="@Model.Subjects ">

I think there is an exception thrown in the Create (POST) method, it then goes to the catch, which returns a view without a model我认为在 Create (POST) 方法中抛出了一个异常,然后它会转到 catch,它返回一个没有模型的视图

    catch
    {
        return View();
    }

The next exception comes while rendering the page trying to bind to @Model.Subjects where Model is null.当呈现页面试图绑定到模型为 null 的@Model.Subjects ,会出现下一个异常。

Remove try/catch or handle the catch to find if there is any exception.删除 try/catch 或处理 catch 以查找是否有任何异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ASP.NET Core 3.1 和 Entity Framework Core:一对多的关系 - ASP.NET Core 3.1 and Entity Framework Core : one-to-many relationship ASP.NET MVC 中与存储库模式的多对多关系 - Many-to-many relation with repository pattern in ASP.NET MVC 更新 asp.net 核心 mvc 中的多对多关系 - Updating a many-to-many relationship in asp.net core mvc 在ASP.net中使用多对多的关系 - Using many to many relationship in ASP.net 插入数据库多对多关系.net core 3.1 - insert into database many to many relationship .net core 3.1 在 asp.net core3.1 webapi 中处理我的多对多关系 api 请求 - Handeling my Many-to-Many relation api requests in asp.net core3.1 webapi 使用 ASP.NET Core 和 Entity Framework Core 不会保存对 ICollection(多对多关系)的更改 - Changes to ICollection (many to many relationship) are not saved using ASP.NET Core and Entity Framework Core ASP.NET 3.1 Web API,实体框架一对多关系要么没有建立要么以循环结束 - ASP.NET 3.1 Web API, Entity Framework one to many relationship either not made or ending in cycle 如何在 ASP.NET CORE WEB API 中实现多对多关系 - How to implement many to many relationship in ASP.NET CORE WEB API ASP.NET Core 3.0 处理多对多关系记录的正确方法 - ASP.NET Core 3.0 the right way of handling many-to-many relationship records
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM