【发布时间】: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<ApplicationUser>(...),因为已经定义了用户实体。也就是说,我建议从第二个实体的定义(也就是我的示例中的badge实体,而不是user info)中定义一对多关系,以避免可能的配置覆盖。 -
尝试重新生成迁移。
ProjectModel.Users集合不存在,或者由于某些未知原因 EF Core 没有看到或忽略它,或者此处未显示一些导航属性。重新生成测试是排除案例#1。从显示的迁移来看,EF Core 似乎考虑了一对多关系。 -
所以应该像这样定义关系
modelBuilder.Entity<Badge>(b => { b.HasKey(x => x.Id); b.HasMany(x => x._users).WithMany(\"Badges\"); });
标签: c# asp.net asp.net-mvc asp.net-core entity-framework-core