【发布时间】:2017-07-04 15:35:10
【问题描述】:
我有 2 个实体:
public partial class GPSdevice
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public GPSdevice()
{
}
public int ID { get; set; }
public string UserName { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual Truck Truck { get; set; }
}
public partial class Truck
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Truck()
{
}
public int TruckID { get; set; }
public string TruckNo { get; set; }
public string Make { get; set; }
[ForeignKey("GPSdevice")]
public int? GPSdeviceID { get; set; }
public virtual GPSdevice GPSdevice { get; set; }
}
我想创建一对一或零的关系(每个 GPS 设备可以链接到任何卡车(但只有一个)或根本不链接)
我写了以下代码:
modelBuilder.Entity<GPSdevice>()
.HasOptional(e => e.Truck)
.WithOptionalPrincipal()
.WillCascadeOnDelete(false);
但它会创建以下迁移:
public override void Up()
{
AddColumn("dbo.Truck", "GPSdevice_ID", c => c.Int());
CreateIndex("dbo.Truck", "GPSdeviceID");
CreateIndex("dbo.Truck", "GPSdevice_ID");
AddForeignKey("dbo.Truck", "GPSdeviceID", "dbo.GPSdevices", "ID");
AddForeignKey("dbo.Truck", "GPSdevice_ID", "dbo.GPSdevices", "ID");
}
为什么要多创建一个字段以及如何改用当前字段 GPSdeviceID?
添加:
如果我删除
public int? GPSdeviceID { get; set; }
并添加 MapKey:
modelBuilder.Entity<GPSdevice>()
.HasOptional(e => e.Truck)
.WithOptionalPrincipal(e=>e.GPSdevice).Map(p=>p.MapKey("GPSdeviceID"))
.WillCascadeOnDelete(false);
结果我得到以下迁移代码:
public override void Up()
{
CreateIndex("dbo.Truck", "GPSdeviceID");
AddForeignKey("dbo.Truck", "GPSdeviceID", "dbo.GPSdevices", "ID");
}
然后我收到以下错误:
引用的表中没有主键或候选键 'dbo.GPSdevices' 匹配外部引用列列表 键“FK_dbo.Truck_dbo.GPSdevices_GPSdeviceID”。无法创建 约束或索引。查看以前的错误。
【问题讨论】:
-
你不能。
HasForeignKeyfluent API 缺少这种类型的关系,目的是表明不支持显式 FK(我不知道为什么)。移除public int? GPSdeviceID { get; set; }属性,最终使用MapKey指定FK数据库列名。 -
@IvanStoev 然后我得到:“引用表 'dbo.GPSdevices' 中没有与外键 'FK_dbo.Truck_dbo.GPSdevices_GPSdeviceID' 中的引用列列表匹配的主键或候选键。可以不创建约束或索引。查看以前的错误。"
-
刚刚注意到您没有正确映射反向导航属性。所以除了第一条评论,把
.WithOptionalPrincipal()改成.WithOptionalPrincipal(e => e.GPSdevice)。 -
那是另一个故事。您在数据库表中有违反约束的现有数据。检查 Truck 表中是否有 GPSdeviceID 值与 GPSDevices 表中的 ID 值不匹配的记录。
-
SQL Server 说您在 GPSDevices 表上没有 ID 列。您可能在测试期间丢失了它。还要检查卡车表。
标签: entity-framework ef-code-first entity-framework-migrations