【问题标题】:EF code first - one-to-one-or-zeroEF 代码优先 - 一对一或零
【发布时间】: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”。无法创建 约束或索引。查看以前的错误。

【问题讨论】:

  • 你不能。 HasForeignKey fluent API 缺少这种类型的关系,目的是表明不支持显式 FK(我不知道为什么)。移除public int? GPSdeviceID { get; set; }属性,最终使用MapKey指定FK数据库列名。
  • @IvanStoev 然后我得到:“引用表 'dbo.GPSdevices' 中没有与外键 'FK_dbo.Truck_dbo.GPSdevices_GPSdeviceID' 中的引用列列表匹配的主键或候选键。可以不创建约束或索引。查看以前的错误。"
  • 刚刚注意到您没有正确映射反向导航属性。所以除了第一条评论,把.WithOptionalPrincipal()改成.WithOptionalPrincipal(e =&gt; e.GPSdevice)
  • 那是另一个故事。您在数据库表中有违反约束的现有数据。检查 Truck 表中是否有 GPSdeviceID 值与 GPSDevices 表中的 ID 值不匹配的记录。
  • SQL Server 说您在 GPSDevices 表上没有 ID 列。您可能在测试期间丢失了它。还要检查卡车表。

标签: entity-framework ef-code-first entity-framework-migrations


【解决方案1】:

使用这个:

public partial class GPSdevice
{       
    public GPSdevice()
    {
    }

    public int ID { get; set; }

    public string UserName { get; set; }


    public virtual Truck Truck { get; set; }

}

public partial class Truck
{       
    public Truck()
    {
    }

    public int TruckID { get; set; }

    public string TruckNo { get; set; }

    public string Make { get; set; }

    public virtual GPSdevice GPSdevice { get; set; }
}   

modelBuilder.Entity<GPSdevice>()
            .HasOptional(o => o.Truck)
            .WithRequired(ad => ad.GPSdevice);

modelBuilder.Entity<Truck>()
    .HasKey(e => e.TruckID);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-06
    • 2015-04-14
    • 2015-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多