[英]Add Foreign Key Column In EF Core
我有一個現有的表Projects
,我想向其中添加UserId
列,其中UserId
是外鍵。 現在的Projects
有一個名稱列表,但是我希望每個用戶都可以管理自己的項目。 我最初擁有“孤兒”是可以的,因為列表足夠小,我可以手動清理它們。
我已經更新了模型,以包含UserId
和導航屬性User
(可能不相關,但是此處的Entity
是具有Id
和DateModified
基類)
public class Project : Entity
{
public string Name { get; set; }
public Guid? UserId { get; set; } //tried this as nullable and non nullable
public User User { get; set; }
}
我相關的映射文件是
public class ProjectMap : IEntityTypeConfiguration<Project>
{
public void Configure(EntityTypeBuilder<Project> builder)
{
builder.Property(x => x.Name).IsRequired();
builder.Property(x => x.UserId).IsRequired();
builder.HasOne(x => x.User)
.WithMany(x => x.Projects)
.HasForeignKey(x => x.UserId)
.OnDelete(DeleteBehavior.SetNull); //I have tried numerous combinations of things here....
}
}
我還向項目的User
實體添加了導航屬性,但未對映射類進行任何更改。
public class User : Entity
{
public string EmailAddress { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public List<Task> Tasks { get; set; }
public List<Project> Projects { get; set; }
}
由此產生的遷移:
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<Guid>(
name: "UserId",
table: "Projects",
nullable: false,
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
migrationBuilder.CreateIndex(
name: "IX_Projects_UserId",
table: "Projects",
column: "UserId");
migrationBuilder.AddForeignKey(
name: "FK_Projects_Users_UserId",
table: "Projects",
column: "UserId",
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.SetNull);
}
運行更新數據庫時會轉換為此SQL
ALTER TABLE [Projects] ADD CONSTRAINT [FK_Projects_Users_UserId] FOREIGN KEY ([UserId]) REFERENCES [Users] ([Id]) ON DELETE SET NULL;
並因該錯誤而失敗
Cannot create the foreign key "FK_Projects_Users_UserId" with the SET NULL referential action, because one or more referencing columns are not nullable.
我究竟做錯了什么?
下面的行導致了此問題,因為您希望Project
FK為空
builder.Property(x => x.UserId).IsRequired();
另外,您生成的遷移已經具有提示:
nullable: false,
只需在您的Configure
方法上刪除該行,它就可以工作。 您可能還需要通過運行Remove-Migration
,然后再次運行add-migration來刪除遷移。 這次您應該具有以下功能:
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Name",
table: "Projects",
nullable: false,
oldClrType: typeof(string),
oldNullable: true);
migrationBuilder.AddColumn<Guid>(
name: "UserId",
table: "Projects",
nullable: true);
migrationBuilder.CreateIndex(
name: "IX_Projects_UserId",
table: "Projects",
column: "UserId");
migrationBuilder.AddForeignKey(
name: "FK_Projects_Users_UserId",
table: "Projects",
column: "UserId",
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.SetNull);
}
如果需要,可以通過在配置關系時顯式設置IsRequired
來更具體:
private static void ConfigureProject(EntityTypeBuilder<Project> b)
{
b.Property(x => x.Name).IsRequired();
b.HasOne(x => x.User)
.WithMany(x => x.Projects)
.HasForeignKey(x => x.UserId)
.IsRequired(false)
.OnDelete(DeleteBehavior.SetNull);
}
即使該屬性已經可以為空,並且EF會使用其約定正確地創建它,我還是喜歡它,對於某些無需閱讀實際Project類就可以閱讀配置並了解它的人來說,它仍然很不錯。
在功能配置中,您可以指定:
builder.Property(x => x.UserId).IsRequired();
這不是說UserId不能為null嗎? 但是您希望它為空嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.