Entity Framework 核心 - 外键 1(额外的外键列)
Entity Framework Core - Foreign Key 1 (extra foreign key column)
我刚刚升级到 Entity Framework Core 2,现在我遇到了一个额外的列存在的问题,并且有一个唯一的键,即使它不在我的模型中,也没有在其他任何地方定义。
指数:
migrationBuilder.CreateTable(
name: "Vouchers",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
Code = table.Column<Guid>(nullable: false),
IsClaimed = table.Column<bool>(nullable: false),
LastModified = table.Column<DateTime>(nullable: false),
NumberOfUnits = table.Column<int>(nullable: false),
TransactionId = table.Column<int>(nullable: false),
TransactionId1 = table.Column<int>(nullable: true) // why is this here?
},
constraints: table =>
{
table.PrimaryKey("PK_Vouchers", x => x.Id);
table.ForeignKey(
name: "FK_Vouchers_Transactions_TransactionId1",
column: x => x.TransactionId1,
principalTable: "Transactions",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
TransactionId1 不在模型中:
public class Voucher : IAutoLastModified
{
public int Id { get; set; }
public DateTime LastModified { get; set; }
public int TransactionId { get; set; }
public Transaction Transaction { get; set; }
public int NumberOfUnits { get; set; }
public Guid Code { get; set; }
public bool IsClaimed { get; set; }
}
我是否错误地定义了外键?
modelBuilder.Entity<Voucher>().HasOne(x => x.Transaction).WithOne(x => x.Voucher).IsRequired(false);
我的应用失败,因为 TransactionId1 始终为 null 并且有一个我无法删除的唯一约束。
为什么 EF 为此 table 创建一个额外的列?
您需要告诉模型构建器您要将 voucher
table 中的哪一列用作外键列。否则 Entity Framework 只会为您创建一个。
为此,请将 HasForeignKey
方法添加到流畅的设置中:
modelBuilder.Entity<Voucher>().HasOne(x => x.Transaction).WithOne(x => x.Voucher).HasForeignKey<Voucher>(x => x.TransactionId).IsRequired(false);
注意在建立一对一关系时,需要将外键所在的实体定义为泛型约束。
好的,所以我弄清楚了问题所在(将问题留在这里,以防犯了与我相同的错误的任何人)。
我将关系标记为可选,但该列是 int
而不是 int?
,因此 EF 决定在幕后添加它自己的列。
修复此问题后,我不得不重新创建数据库 - 由于现有数据,迁移未成功完成。
我过去曾使用数据优先方法遇到过这个问题。我不得不删除一个现有的列,但在每次更新后,该列都会出现在 edmx 模式结构中,我必须手动删除它才能使其工作。你能重新创建 edmx 而不是更新吗?
我遇到了同样的问题,我的解决方法是在导航 属性 上方添加 [Foreign Key("")] 的数据注释标签,以明确说明要使用哪个。
public Guid TransactionId { get; set; }
[ForeignKey("TransactionId ")]
public Transaction Transaction { get; set; }
谢谢
如果您将模型定义为双向绑定但忘记流畅地使用它,也可能会发生这种情况:
public class Customer
{
public Guid Id { get; set; }
public List<Order> Orders {get; set;}
}
public class Order
{
public Guid Id { get; set; }
public Guid CustomerId { get; set; }
public Guid Customer { get; set; }
}
// AppDbContext
builder.Entity<Order>()
.HasOne(x => x.Customer) // <-- EDIT: Also use it like this, not .HasOne<Customer>()
.WithMany() //WRONG -> should be .WithMany(x => x.Orders) OR modify the model to not define the collection at the customer entity
.HasForeignKey(x => x.CustomerId)
.OnDelete(DeleteBehavior.SetNull)
;
当子项中的外键字段类型与父项中的主键字段类型不匹配时,我遇到了这个问题。
示例:
public class User // Parent
{
public long Id { get; set; }
public virtual ICollection<UserLike> UserLikes { get; set; } // Child collection
}
public class UserLike // Child
{
public int Id { get; set; }
public int UserId { get; set; } // Foreign key
public virtual User User { get; set; } // Navigation property
}
在 DbContext 中,我有:
modelBuilder.Entity<UserLike>(entity =>
{
entity.HasOne(x => x.User)
.WithMany(x => x.UserLikes)
.OnDelete(DeleteBehavior.ClientCascade);
}
此处,int UserId
与父类中的主键long Id
类型不匹配。解决方案是使 UserId
long
:
public class UserLike // Child
{
public int Id { get; set; }
public long UserId { get; set; } // Foreign key
public virtual User User { get; set; } // Navigation property
}
我刚刚升级到 Entity Framework Core 2,现在我遇到了一个额外的列存在的问题,并且有一个唯一的键,即使它不在我的模型中,也没有在其他任何地方定义。
指数:
migrationBuilder.CreateTable(
name: "Vouchers",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
Code = table.Column<Guid>(nullable: false),
IsClaimed = table.Column<bool>(nullable: false),
LastModified = table.Column<DateTime>(nullable: false),
NumberOfUnits = table.Column<int>(nullable: false),
TransactionId = table.Column<int>(nullable: false),
TransactionId1 = table.Column<int>(nullable: true) // why is this here?
},
constraints: table =>
{
table.PrimaryKey("PK_Vouchers", x => x.Id);
table.ForeignKey(
name: "FK_Vouchers_Transactions_TransactionId1",
column: x => x.TransactionId1,
principalTable: "Transactions",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
TransactionId1 不在模型中:
public class Voucher : IAutoLastModified
{
public int Id { get; set; }
public DateTime LastModified { get; set; }
public int TransactionId { get; set; }
public Transaction Transaction { get; set; }
public int NumberOfUnits { get; set; }
public Guid Code { get; set; }
public bool IsClaimed { get; set; }
}
我是否错误地定义了外键?
modelBuilder.Entity<Voucher>().HasOne(x => x.Transaction).WithOne(x => x.Voucher).IsRequired(false);
我的应用失败,因为 TransactionId1 始终为 null 并且有一个我无法删除的唯一约束。
为什么 EF 为此 table 创建一个额外的列?
您需要告诉模型构建器您要将 voucher
table 中的哪一列用作外键列。否则 Entity Framework 只会为您创建一个。
为此,请将 HasForeignKey
方法添加到流畅的设置中:
modelBuilder.Entity<Voucher>().HasOne(x => x.Transaction).WithOne(x => x.Voucher).HasForeignKey<Voucher>(x => x.TransactionId).IsRequired(false);
注意在建立一对一关系时,需要将外键所在的实体定义为泛型约束。
好的,所以我弄清楚了问题所在(将问题留在这里,以防犯了与我相同的错误的任何人)。
我将关系标记为可选,但该列是 int
而不是 int?
,因此 EF 决定在幕后添加它自己的列。
修复此问题后,我不得不重新创建数据库 - 由于现有数据,迁移未成功完成。
我过去曾使用数据优先方法遇到过这个问题。我不得不删除一个现有的列,但在每次更新后,该列都会出现在 edmx 模式结构中,我必须手动删除它才能使其工作。你能重新创建 edmx 而不是更新吗?
我遇到了同样的问题,我的解决方法是在导航 属性 上方添加 [Foreign Key("")] 的数据注释标签,以明确说明要使用哪个。
public Guid TransactionId { get; set; }
[ForeignKey("TransactionId ")]
public Transaction Transaction { get; set; }
谢谢
如果您将模型定义为双向绑定但忘记流畅地使用它,也可能会发生这种情况:
public class Customer
{
public Guid Id { get; set; }
public List<Order> Orders {get; set;}
}
public class Order
{
public Guid Id { get; set; }
public Guid CustomerId { get; set; }
public Guid Customer { get; set; }
}
// AppDbContext
builder.Entity<Order>()
.HasOne(x => x.Customer) // <-- EDIT: Also use it like this, not .HasOne<Customer>()
.WithMany() //WRONG -> should be .WithMany(x => x.Orders) OR modify the model to not define the collection at the customer entity
.HasForeignKey(x => x.CustomerId)
.OnDelete(DeleteBehavior.SetNull)
;
当子项中的外键字段类型与父项中的主键字段类型不匹配时,我遇到了这个问题。
示例:
public class User // Parent
{
public long Id { get; set; }
public virtual ICollection<UserLike> UserLikes { get; set; } // Child collection
}
public class UserLike // Child
{
public int Id { get; set; }
public int UserId { get; set; } // Foreign key
public virtual User User { get; set; } // Navigation property
}
在 DbContext 中,我有:
modelBuilder.Entity<UserLike>(entity =>
{
entity.HasOne(x => x.User)
.WithMany(x => x.UserLikes)
.OnDelete(DeleteBehavior.ClientCascade);
}
此处,int UserId
与父类中的主键long Id
类型不匹配。解决方案是使 UserId
long
:
public class UserLike // Child
{
public int Id { get; set; }
public long UserId { get; set; } // Foreign key
public virtual User User { get; set; } // Navigation property
}