【问题标题】:Issue with Database Migrations on Entity Framework 6Entity Framework 6 上的数据库迁移问题
【发布时间】:2015-09-01 11:14:51
【问题描述】:

我有以下课程(为简洁起见);

public class InsurancePolicy : AuditableEntity<int>
{
    [Column("id"), Key]
    public override int ID { get; set; }
    [Column("deviceid"), ForeignKey("Device")]
    public int DeviceId { get; set; }
    public virtual Device Device { get; set; }
}

public partial class Device : AuditableEntity<int>
{
    [Column("deviceid"), Key]
    public override int ID { get; set; }

    [ForeignKey("Policy")]
    public int PolicyId { get; set; }
    public virtual InsurancePolicy Policy { get; set; }

    [ForeignKey("Vehicle")]
    public int VehicleId { get; set; }
    public virtual Vehicle Vehicle { get; set; }
}

public partial class Vehicle : AuditableEntity<int>
{
    [Column("id"), Key]
    public override int ID { get; set; }

    [Column("deviceid"), ForeignKey("Device")]
    public int DeviceId { get; set; }
    public virtual Device Device { get; set; }

    public virtual List<InsurancePolicyVehicle> InsurancePolicyVehicles { get; set; }
}

现在,当我尝试运行 update-database 命令时,出现此错误:

Device_Policy_Target: : 多重性在关系“Device_Policy”中的角色“Device_Policy_Target”中无效。因为从属角色属性不是关键属性,所以从属角色的多重性的上限必须是“*”。

Device_Vehicle_Target::多重性在关系“Device_Vehicle”中的角色“Device_Vehicle_Target”中无效。由于 Dependent Role 属性不是关键属性,因此 Dependent Role 多重性的上限必须为“*”。

谁能告诉我这里做错了什么?

【问题讨论】:

  • 我觉得类之间有交叉关系。 'InsurancePolicy'类同时引用'Device'类,它也引用回来。我认为这是不可接受的。请优化表关系

标签: c# entity-framework


【解决方案1】:

Device_Policy_Target 关系为例,您有以下内容(精简到此关系的相关属性):

public class InsurancePolicy : AuditableEntity<int>
{   
    [Column("id"), Key]
    public override int ID { get; set; }
    [Column("deviceid"), ForeignKey("Device")]
    public int DeviceId { get; set; }
    public virtual Device Device { get; set; }
}

public partial class Device : AuditableEntity<int>
{
    [Column("deviceid"), Key]
    public override int ID { get; set; }

    [ForeignKey("Policy")]
    public int PolicyId { get; set; }
    public virtual InsurancePolicy Policy { get; set; }

}

您在这里定义的是一对一的关系。 EF 仅支持两个表共享主键的这种关系。在您的配置中,您的子表 - InsurancePolicy 有自己的 PK 和 Device 的外键。 EF 仅支持具有这些约束的一对多关系。

要将这些关系定义为一对一,请将您的设置切换为以下内容:

public class InsurancePolicy : AuditableEntity<int>
{
    [Column("deviceid"), Key, ForeignKey("Device")]
    public override int ID { get; set; }
    public virtual Device Device { get; set; }
}

public partial class Device : AuditableEntity<int>
{
    [Column("deviceid"), Key]
    public override int ID { get; set; }

    public virtual InsurancePolicy Policy { get; set; }    
}

这部分是 EF 不支持唯一约束的结果。 This article 使用 DataAnnotations 对一对一关系进行了更全面的解释

更新:

要使用您所拥有的表/键“伪造”一对一,然后考虑这样的事情:

public class InsurancePolicy : AuditableEntity<int>
{   
    [Column("id"), Key]
    public override int ID { get; set; }
    [Column("deviceid"), ForeignKey("Device")]
    public int DeviceId { get; set; }
    public virtual Device Device { get; set; }
}

public partial class Device : AuditableEntity<int>
{
    [Column("deviceid"), Key]
    public override int ID { get; set; }

    public virtual IEnumerable<InsurancePolicy> PoliciesAsList { get; set; }

    [NotMapped]
    public virtual InsurancePolicy Policy {
        get {
            return (PoliciesAsList != null) 
                ? PoliciesAsList.FirstOrDefault() 
                : null;                
        }
    }

}

在这种情况下,我任意选择了 Device 作为父级 - 你选择哪个并不重要。

您还应该确保数据库对 InsurancePolicy 表上的 deviceid 具有唯一约束。

【讨论】:

  • 您好乔恩,感谢您的回复。我在这里遇到的唯一问题是这些表存在于数据库中(即 deviceid 是设备中的 PK,id 是 InsurancePolicy 中的 PK)。所以我需要保留例如 [Column("id"), Key] public override int ID { get;放; } 因为 PK 在 db 中有效,并且 dba 不允许更改它。在这种情况下有什么建议吗?
  • 嗨,乔恩,非常感谢您抽出宝贵时间查看此内容。我需要调整表并对表进行一些更改,但有人告诉我必须保留现有的列名。因此,在这种情况下,设备可以独立于策略而存在,反之亦然。它们最终可以并且将被链接(即,一旦它们被分配等)。
  • 您必须在 EF 中将它们切换为一对多关系 - 至少对于配置而言。您始终可以添加一个附加属性来检索列表中的第一项(如果存在),否则为 null。
  • 只是添加,所以我想要实现的只是在保险单中有一个 deviceid 列(可以为空)和设备表中的 policyid 列,同样可以为空。然后,当设备被分配给他的策略时,这将被简单地填写。为了便于在 EF 中使用,我希望能够访问任何一方的表单(即从设备获取策略,反之亦然)。这可能吗?
  • 选择一个作为名义上的父母 - 你不需要两边都有 ID 来建立链接。
猜你喜欢
  • 2011-01-12
  • 2022-12-09
  • 2018-11-05
  • 2019-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-20
相关资源
最近更新 更多