【问题标题】:How to create many-to-many relationship with custom ApplicationUser class MVC?如何使用自定义 ApplicationUser 类 MVC 创建多对多关系?
【发布时间】:2022-08-20 19:39:41
【问题描述】:

我需要链接两个表(使用自定义 ApplicationUser 类的 AspNetUsers 和自定义 Projects 类)。我希望用户有多个项目,反之亦然。我已将以下代码添加到我的两个模型中;但是,在进行迁移和更新数据库时,不会创建链接表。

这是我的 ApplicationUser 类:

using System;
using System.Security.Claims;
using IssueTracker.Models;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Identity;

namespace IssueTracker.Areas.Identity.Data
{
    public class ApplicationUser : IdentityUser
    {
        public ApplicationUser()
        {
            this.Projects = new HashSet<ProjectModel>();
        }

        public String? FirstName { get; set; }

        public String? LastName { get; set; }

        public String? Role { get; set; }

        public virtual ICollection<ProjectModel> Projects { get; set; }
    }
}

这是我的项目模型类:

using System;
using Microsoft.AspNetCore.Identity;
using IssueTracker.Areas.Identity.Data;
using System.ComponentModel.DataAnnotations;

namespace IssueTracker.Models
{
    public class ProjectModel
    {
        public ProjectModel()
        {
            this.Users = new HashSet<ApplicationUser>();
        }

        public int Id { get; set; }

        public string? Name { get; set; }

        public string? Description { get; set; }

        public virtual ICollection<ApplicationUser> Users { get; set; }

    }
}


这是我的 DbContext:

using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using IssueTracker.Models;

namespace IssueTracker.Areas.Identity.Data;

public class IssueTrackerIdentityDbContext : IdentityDbContext<ApplicationUser>
{
    public DbSet<ProjectModel> Projects { get; set; }

    public IssueTrackerIdentityDbContext()
    {

    }

    public IssueTrackerIdentityDbContext(DbContextOptions<IssueTrackerIdentityDbContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        // Customize the ASP.NET Identity model and override the defaults if needed.
        // For example, you can rename the ASP.NET Identity table names and more.
        // Add your customizations after calling base.OnModelCreating(builder);

        builder.ApplyConfiguration(new ApplicationUserEntityConfiguration());
    }


}

public class ApplicationUserEntityConfiguration : IEntityTypeConfiguration<ApplicationUser>
{
    public void Configure(EntityTypeBuilder<ApplicationUser> builder)
    {
        builder.Property(u => u.FirstName).HasMaxLength(255);
        builder.Property(u => u.LastName).HasMaxLength(255);
    }
}

在使用上面的代码运行迁移后,我得到了这个迁移,它不会创建一个表来链接两者。

using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace IssueTracker.Migrations
{
    public partial class UserProjectTable : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.RenameColumn(
                name: \"ID\",
                table: \"Projects\",
                newName: \"Id\");

            migrationBuilder.AddColumn<string>(
                name: \"ApplicationUserId\",
                table: \"Projects\",
                type: \"TEXT\",
                nullable: true);

            migrationBuilder.CreateIndex(
                name: \"IX_Projects_ApplicationUserId\",
                table: \"Projects\",
                column: \"ApplicationUserId\");

            migrationBuilder.AddForeignKey(
                name: \"FK_Projects_AspNetUsers_ApplicationUserId\",
                table: \"Projects\",
                column: \"ApplicationUserId\",
                principalTable: \"AspNetUsers\",
                principalColumn: \"Id\");
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropForeignKey(
                name: \"FK_Projects_AspNetUsers_ApplicationUserId\",
                table: \"Projects\");

            migrationBuilder.DropIndex(
                name: \"IX_Projects_ApplicationUserId\",
                table: \"Projects\");

            migrationBuilder.DropColumn(
                name: \"ApplicationUserId\",
                table: \"Projects\");

            migrationBuilder.RenameColumn(
                name: \"Id\",
                table: \"Projects\",
                newName: \"ID\");
        }
    }
}

我应该如何更新我的代码,以便我可以在 ApplicationUser 和 Projects 之间正确创建多对多关系。此外,一旦创建了这种关系,我如何才能正确访问和修改关系。每当将用户添加到项目中时(反之亦然),我是否需要更新所有 3 个类,或者我只需要更新链接表。太感谢了!我是 MVC 的新手,所以如果这是非常初级的,请原谅我。

  • 关于在 EFCore 上创建多对多关系,您可以在 Implementation problem of storing and reusing objects with the same data 查看我最近的回答。
  • 是的,但是由于我使用的是内置于 Identity 的 AspNetUsers 表,我是否还需要在 DbContext 中创建 ApplicationUsers 的 DbSet?
  • 不,已经定义了一个,称为Users。这意味着您也不需要调用modelBuilder.Entity&lt;ApplicationUser&gt;(...),因为已经定义了用户实体。也就是说,我建议从第二个实体的定义(也就是我的示例中的badge 实体,而不是user info)中定义一对多关系,以避免可能的配置覆盖。
  • 尝试重新生成迁移。 ProjectModel.Users 集合不存在,或者由于某些未知原因 EF Core 没有看到或忽略它,或者此处未显示一些导航属性。重新生成测试是排除案例#1。从显示的迁移来看,EF Core 似乎考虑了一对多关系。
  • 所以应该像这样定义关系modelBuilder.Entity&lt;Badge&gt;(b =&gt; { b.HasKey(x =&gt; x.Id); b.HasMany(x =&gt; x._users).WithMany(\"Badges\"); });

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


【解决方案1】:

也试试这个:

public class ApplicationUserEntityConfiguration : 
IEntityTypeConfiguration<ApplicationUser>
{
public void Configure(EntityTypeBuilder<ApplicationUser> builder)
{
    builder.Property(u => u.FirstName).HasMaxLength(255);
    builder.Property(u => u.LastName).HasMaxLength(255);


    builder.HasMany(x => x.Projects).WithMany(x => x.Users);
}
}

【讨论】:

    猜你喜欢
    • 2022-01-12
    • 1970-01-01
    • 2021-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 2017-07-01
    • 2016-01-06
    相关资源
    最近更新 更多