插入到 EF Core ASP.NET Core Razor Pages .NET6 中自动生成的 Bridge 表

Posted

技术标签:

【中文标题】插入到 EF Core ASP.NET Core Razor Pages .NET6 中自动生成的 Bridge 表【英文标题】:Insert to autogenerated Bridge table in EF Core ASP.NET Core Razor Pages .NET6 【发布时间】:2022-01-17 10:49:39 【问题描述】:

我是 EF 新手,需要帮助理解以下内容: 我在数据库中有一个班级表和一个学生表。一个班级可以有很多学生,一个学生可以在多个班级。我有一个由 EF 核心自动生成的表,名为 ClassModelStudent。它有以下字段:

我创建了一个剃须刀页面来创建课程,并且在发布事件时,按钮应该发送 ClassID 并重定向到 AddStudents 页面。

AddStudents Class 的代码如下:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using TestProject.Model;

namespace TestProject.Pages.Classes

    public class EnrollmentModel : PageModel
    
        private readonly TestProject.Data.TestProjectContext _context;

    public EnrollmentModel(TestProject.Data.TestProjectContext context)
    
        _context = context;
    
    [BindProperty]
   public Enrollment Enrollments  get; set;    
    public SelectList Classes  get; set;     
    public IList<Student> UserProfile  get; set; 
    [BindProperty(SupportsGet = true)]
    public string? SearchString  get; set; 
    public async Task OnGetAsync()
    
        var students = from s in _context.User_Profile
                       select s;
        if (!string.IsNullOrEmpty(SearchString))
        
            students = students.Where(s => s.FirstName.Contains(SearchString));
        

        UserProfile = await students.ToListAsync();

        var classes = from i in _context.Class
                          orderby i.Description
                          select i;

        Classes = new SelectList(classes, "ClassID", 
"Description");

    

    public async Task<IActionResult> OnPostAsync()
    
        if (!ModelState.IsValid)
        

            return Page();
        
       //THIS IS WHERE I TRIED ACCESSING CLASSMODELSTUDENT TABLE 
      //AND THE CONTEXT DID NOT SEE IT
       // _context.e
        await _context.SaveChangesAsync();

        return RedirectToPage("./Index");
    

我目前已将其连接到 Enrollments 表。我什至不确定是否应该将其写入自动生成的表 ClassModelStudents 或手动创建的 Enrollments? 注册表如下所示:

在 AddStudents 页面中,我在表格中显示学生列表。我在表格的每一行中创建了“添加到类”按钮。当单击“添加到班级”按钮时,我想将该学生添加到所选班级。我应该写给 ClassModelStudents 表。 请看下面的 AddStudents 页面截图:

我不明白的是如何为 ClassModelStudent 创建类(模型)?因为我无法使用上下文直接访问此表。如何访问该表以将 ClassID 和 StudentID 写入其中?

请指教.. 非常感谢您的帮助..

以下是我的 ClassModel 模型类:

 public class ClassModel


    [Key]
    [Required]
    [Display(Name ="Class ID")]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ClassID  get; set; 
    //[ForeignKey("UserProfile")]
    //[Display(Name = "User ID")]
    //public virtual int ID  get; set; 
    [Required]
    public string Description  get; set;  
    [Required]
    public int Occurence  get; set; 
    [Required]
    [DataType(DataType.Date)]
    public DateTime Startdate  get; set; 
    [Required]
    [DataType(DataType.Time)]
    public DateTime From  get; set; 
    [Required]
    [DataType(DataType.Time)]
    //[GreaterThanOrEqualTo("From")]
    public DateTime To  get; set; 
    [Required]
    [DataType(DataType.Currency)]
    public double Fees  get; set; 

    [DisplayFormat(NullDisplayText = "No Instructor Assigned")]
    [ForeignKey("InstructorID")]
    public virtual int InstructorID  get; set; 
    public Instructor? Instructor  get; set; 

    [DisplayFormat(NullDisplayText = "No Student Assigned")]
    public ICollection<Student>? Students  get; set; 

    public ICollection<Enrollment>? Enrollment   get; set; 

这是注册类模型:

public class Enrollment

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int EnrollmentID  get; set; 
    [Required]

    [ForeignKey("ClassID")]
    public virtual int ClassID  get; set; 
    [Required]
    [ForeignKey("StudentID")]
    public virtual int StudentID  get; set; 
    [Required]
    public ClassModel? Class  get; set; 
    [Required]
    public Student? Student  get; set; 

    


以下是学生模型:

public class Student

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Display(Name = "StudentID")]
    public int StudentID  get; set; 
    [Required]
      
    public string FirstName  get; set; 

    [Required]

    public string LastName  get; set; 
   
    
    [Required]
    public Boolean Status  get; set; 
    [DataType(DataType.Date)]
    public DateTime DateOfBirth  get; set; 
    [Required]
    [DataType(DataType.EmailAddress)]
    public string Email  get; set; 
    [Required]
    [Phone]
    [DataType(DataType.PhoneNumber)]
    public string PhoneNumber  get; set; 

    public string EmergencyContactName  get; set; 
    [Phone]
    [DataType(DataType.PhoneNumber)]
    public string EmergencyContactNumber  get; set; 

    [Required]
    public string Gender  get; set; 

    public string FullName
    
        get  return LastName + ", " + FirstName; 
    
    [DisplayFormat(NullDisplayText = "No Class Assigned")]
    public ICollection<ClassModel>? Classes  get; set; 

    public ICollection<Enrollment>? Enrollments  get; set;     

我没有 ClassModelStudent 的代码,因为它是自动生成的。

【问题讨论】:

您需要在现有的控制器操作中向我们展示您的代码。 嗨@Dai,我已经修改了帖子并添加了addstudents.cshtml.cs文件代码。我正在使用 Razor 页面。希望它有助于理解我的问题。 ***.com/questions/38893873/… 嗨@Reet,你能提供你的模型设计和AddClassAddstudent页面视图吗? 从你提供的图片看,你好像不止3张桌子,你能提供所有的模型设计吗?在我看来,你有一个class table,一个student table和一个@987654338 @,但我不知道Enrollments table是什么。 【参考方案1】:

当你在TestProjectContext中创建many-to-many关系时,你写的代码是不是像:

    .......

    public Dbset<Class> classes;
    public Dbset<students> students;

ClassModelStudent表是EF核心自动生成的,所以不能用_context.ClassModelStudent插入数据?

如果你的问题和我上面提到的一样,你可以用另一种方法创建many-to-many关系,我写一个简单的demo:

型号

 public class Group
    
        public int Id  get; set; 
        public string GroupName  get; set; 
        public List<GroupMembers> GroupMembers  get; set; 
    

public class User
    
        public int Id  get; set; 
        public string UserName  get; set; 
        public List<GroupMembers> GroupMembers  get; set; 
    

public class GroupMembers
    
        public int Id  get; set; 
        public int UserId  get; set; 
        public User user  get; set; 

        public int GroupId  get; set; 
        public Group group  get; set; 
    

数据上下文

public class WebTestContext : DbContext
    
        public WebTestContext(DbContextOptions<WebTestContext> options):base(options)
        

        

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        
            modelBuilder.Entity<GroupMembers>()
                .HasKey(gm => new  gm.UserId, gm.GroupId );
            modelBuilder.Entity<GroupMembers>()
                .HasOne(gm => gm.group)
                .WithMany(group=> group.GroupMembers)
                .HasForeignKey(gm => gm.GroupId);
            modelBuilder.Entity<GroupMembers>()
                .HasOne(gm => gm.user)
                .WithMany(user => user.GroupMembers)
                .HasForeignKey(gm => gm.UserId);
        
        public DbSet<User> usertable  get; set; 
        public DbSet<Group> grouptable  get; set; 
        public DbSet<GroupMembers> GroupMembers  get; set; 
    

这样在DataContext中创建多对多关系,可以在pagemodel中使用_context.(Relational tables)

================================================ =============

如果Enrollment表是ClassModelStudent的关系表,则不需要让EF核心创建其他关系表。

型号

public class ClassModel
    
        [Key]
        public int ClassID  get; set; 
        public string Description  get; set; 
        public string ClassName  get; set; 
        
        public ICollection<Enrollment>? Enrollments  get; set; 
    

public class Enrollment
    
        [Key]
        public int EnrollmentID  get; set; 
        

        [ForeignKey("ClassID")]
        public virtual int ClassID  get; set; 
        [Required]
        [ForeignKey("StudentID")]
        public virtual int StudentID  get; set; 
        [Required]
        public ClassModel? Class  get; set; 
        [Required]
        public Student? Student  get; set; 
    

public class Student
    
        [Key]
        public int StudentID  get; set; 
        public string FirstName  get; set; 
        public string Email  get; set; 

        public ICollection<Enrollment>? Enrollments  get; set; 
    

TestProjectContext

public class TestProjectContext : DbContext
    
        public TestProjectContext(DbContextOptions<TestProjectContext> options) : base(options)
        

        

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        
            modelBuilder.Entity<Enrollment>()
                .HasKey(gm => new  gm.ClassID, gm.StudentID );
            modelBuilder.Entity<Enrollment>()
                .HasOne(gm => gm.Class)
                .WithMany(group => group.Enrollments)
                .HasForeignKey(gm => gm.ClassID);
            modelBuilder.Entity<Enrollment>()
                .HasOne(gm => gm.Student)
                .WithMany(user => user.Enrollments)
                .HasForeignKey(gm => gm.StudentID);
        

        public DbSet<ClassModel> ClassModels  get; set; 
        public DbSet<Student> students  get; set; 
        public DbSet<Enrollment> enrollments  get; set; 
    

那么,你只有三个表

您可以在 PageModel 中使用它们中的任何一个

【讨论】:

嗨,@Xinran,我没有单独的 DbContext 类。我正在使用 .NET6 。我需要创建一个吗? 嗨@Xinran,我已经修改了帖子并添加了Class、Student和Enrollments的所有数据模型代码。将学生添加到班级时,我应该将记录添加到 Enrollments 表中,而不是触摸 ClassModelStudents 表吗?你有什么建议? 嗨@Reet,您可以将TestProjectContext 更改为我上面显示的相同格式。 嗨@Xinran,我需要将它写入 Enrollment 表,但我的上下文仍然没有看到这个表。 Classstudens 是多对多关系,Enrollment 是它们的关系表,对吧?

以上是关于插入到 EF Core ASP.NET Core Razor Pages .NET6 中自动生成的 Bridge 表的主要内容,如果未能解决你的问题,请参考以下文章

带有 EF Core 的 ASP.NET Core - DTO 集合映射

EF Core ASP.Net Core 编辑迁移

ASP.Net Core 如何在 EF Core 和 Identity 中获取用户角色

asp.net core, Ef core : 在运行时动态映射存储库和服务

ASP.NET Core 使用 EF Core

如何使用 ASP.NET Core 设置 EF6 迁移