EF Core 2.1:具有一对多关系的自引用实体生成附加列
EF Core 2.1: Self-referencing entity with one to many relationship generates additional column
我有以下实体:
public class Level
{
public int LevelId { get; set; }
public int? ParentLevelId { get; set; }
public string Name { get; set; }
public virtual Level Parent { get; set; }
public virtual HashSet<Level> Children { get; set; }
}
我在这里遇到的麻烦是 Children
属性,它在 Fluent API 中是这样配置的:
modelBuilder.Entity<Level>()
.HasOne(x => x.Parent)
.WithMany(x => x.Children)
.HasForeignKey(x => x.ParentLevelId);
这会导致迁移添加一些额外的列:
migrationBuilder.AddColumn<int>(
name: "LevelId1",
table: "Level",
nullable: true);
migrationBuilder.CreateIndex(
name: "IX_Level_LevelId1",
table: "Level",
column: "LevelId1");
migrationBuilder.AddForeignKey(
name: "FK_Level_Level_LevelId1",
table: "Level",
column: "LevelId1",
principalTable: "Level",
principalColumn: "LevelId",
onDelete: ReferentialAction.Restrict);
我做错了什么?
编辑:问题被标记为可能与 重复;然而,在这种情况下,模型生成工作正常——问题在于加载数据。而这里的问题是生成了一个额外的列。
您的迁移出现问题。初始化该模型时没有重现:
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace EfCoreTest
{
public class Level
{
public int LevelId { get; set; }
public int? ParentLevelId { get; set; }
public string Name { get; set; }
public virtual Level Parent { get; set; }
public virtual HashSet<Level> Children { get; set; }
}
public class Db : DbContext
{
public DbSet<Level> levels { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("server=.;database=EfCoreTest;Integrated Security=true");
base.OnConfiguring(optionsBuilder);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Level>()
.HasOne(x => x.Parent)
.WithMany(x => x.Children)
.HasForeignKey(x => x.ParentLevelId);
}
}
class Program
{
static void Main(string[] args)
{
using (var db = new Db())
{
db.Database.EnsureDeleted();
db.Database.EnsureCreated();
Console.ReadKey();
}
}
}
}
创建 table:
CREATE TABLE [levels] (
[LevelId] int NOT NULL IDENTITY,
[ParentLevelId] int NULL,
[Name] nvarchar(max) NULL,
CONSTRAINT [PK_levels] PRIMARY KEY ([LevelId]),
CONSTRAINT [FK_levels_levels_ParentLevelId] FOREIGN KEY ([ParentLevelId]) REFERENCES [levels] ([LevelId]) ON DELETE NO ACTION
);
添加了迁移,
PM> Add-Migration InitialCreate
仍然没有重现:
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
namespace EfCoreTest.Migrations
{
public partial class InitialCreate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "levels",
columns: table => new
{
LevelId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
ParentLevelId = table.Column<int>(nullable: true),
Name = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_levels", x => x.LevelId);
table.ForeignKey(
name: "FK_levels_levels_ParentLevelId",
column: x => x.ParentLevelId,
principalTable: "levels",
principalColumn: "LevelId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex(
name: "IX_levels_ParentLevelId",
table: "levels",
column: "ParentLevelId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "levels");
}
}
}
我有以下实体:
public class Level
{
public int LevelId { get; set; }
public int? ParentLevelId { get; set; }
public string Name { get; set; }
public virtual Level Parent { get; set; }
public virtual HashSet<Level> Children { get; set; }
}
我在这里遇到的麻烦是 Children
属性,它在 Fluent API 中是这样配置的:
modelBuilder.Entity<Level>()
.HasOne(x => x.Parent)
.WithMany(x => x.Children)
.HasForeignKey(x => x.ParentLevelId);
这会导致迁移添加一些额外的列:
migrationBuilder.AddColumn<int>(
name: "LevelId1",
table: "Level",
nullable: true);
migrationBuilder.CreateIndex(
name: "IX_Level_LevelId1",
table: "Level",
column: "LevelId1");
migrationBuilder.AddForeignKey(
name: "FK_Level_Level_LevelId1",
table: "Level",
column: "LevelId1",
principalTable: "Level",
principalColumn: "LevelId",
onDelete: ReferentialAction.Restrict);
我做错了什么?
编辑:问题被标记为可能与
您的迁移出现问题。初始化该模型时没有重现:
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace EfCoreTest
{
public class Level
{
public int LevelId { get; set; }
public int? ParentLevelId { get; set; }
public string Name { get; set; }
public virtual Level Parent { get; set; }
public virtual HashSet<Level> Children { get; set; }
}
public class Db : DbContext
{
public DbSet<Level> levels { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("server=.;database=EfCoreTest;Integrated Security=true");
base.OnConfiguring(optionsBuilder);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Level>()
.HasOne(x => x.Parent)
.WithMany(x => x.Children)
.HasForeignKey(x => x.ParentLevelId);
}
}
class Program
{
static void Main(string[] args)
{
using (var db = new Db())
{
db.Database.EnsureDeleted();
db.Database.EnsureCreated();
Console.ReadKey();
}
}
}
}
创建 table:
CREATE TABLE [levels] (
[LevelId] int NOT NULL IDENTITY,
[ParentLevelId] int NULL,
[Name] nvarchar(max) NULL,
CONSTRAINT [PK_levels] PRIMARY KEY ([LevelId]),
CONSTRAINT [FK_levels_levels_ParentLevelId] FOREIGN KEY ([ParentLevelId]) REFERENCES [levels] ([LevelId]) ON DELETE NO ACTION
);
添加了迁移,
PM> Add-Migration InitialCreate
仍然没有重现:
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
namespace EfCoreTest.Migrations
{
public partial class InitialCreate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "levels",
columns: table => new
{
LevelId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
ParentLevelId = table.Column<int>(nullable: true),
Name = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_levels", x => x.LevelId);
table.ForeignKey(
name: "FK_levels_levels_ParentLevelId",
column: x => x.ParentLevelId,
principalTable: "levels",
principalColumn: "LevelId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex(
name: "IX_levels_ParentLevelId",
table: "levels",
column: "ParentLevelId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "levels");
}
}
}