在遗留数据中实现外键

时间:2018-03-12 15:29:11

标签: c# sql entity-framework asp.net-core

我最近为公司重建了一个内部网站,我们不得不从旧应用程序导入数据,这些数据没有外键关系,更不用说限制了。所有的关系都是在代码方面处理的。

现在它已经使用具有强大类型和关系的.NET Core 2.0和Entity Framework进行了重建,现在有很多遗留数据绊倒了我的EF迁移。

例如,我们有一个Companies表,其中有一个“负责员工”,基于该员工的LdapID。但是,旧的遗留数据还有超过2,000个条目,其中有人刚刚输入了员工的姓名而不是他们的ID。我没有权限清理这些数据,所以这不是一个选项。

该站点已经构建为在旧数据中显示这些“坏”值,但由于FK约束,我的所有迁移都失败了;例如,Employee ID Smith, BobEmployee表中的任何ID都不匹配。有没有办法可以对新数据强制执行外键关系,同时允许旧的旧数据继续使用“坏”值?现在,当我尝试在添加新列后运行迁移时,这就是我得到的:

  

ALTER TABLE语句与FOREIGN KEY约束冲突   “FK_Companies_Employees_EmployeeID”。冲突发生在数据库中   “ets_web”,表“dbo.Employees”,列“LdapID”。

暂时的一次性修复对我不起作用。我需要能够创建可以由我们的测试和生产环境中的自动化流程运行的迁移。我可以删除所有约束,但我宁愿把它作为最后的手段。

使属性可以为空可以解决这个问题,因为它们已经是可以为空的类型,并且空值不是问题。在外表[{1}}中不存在外键Company.EmployeeID时。其他表中也存在类似的问题。

Company.cs

Employee

Employee.cs

public class Company
{
    #region Main Properties
    public int ID { get; set; }

    [Required, StringLength(100)]
    [Display(Name = "Company Name")]
    public string Name { get; set; }

    [Required, StringLength(50)]
    [Display(Name = "Address Line 1")]
    public string AddressLine1 { get; set; }

    [StringLength(50)]
    [Display(Name = "Address Line 2")]
    public string AddressLine2 { get; set; }

    [StringLength(50)]
    [Display(Name = "Address Line 3")]
    public string AddressLine3 { get; set; }

    [StringLength(50)]
    [Display(Name = "City")]
    public string City { get; set; }

    [Display(Name = "State / Province")]
    public string StateID { get; set; }

    [DefaultValue("US")]
    [Display(Name = "Country")]
    public string CountryID { get; set; }

    [Required, StringLength(7, ErrorMessage = "Zip / Postal Code must be 7 characters or less."), DataType(DataType.PostalCode)]
    [Display(Name = "Zip / Postal Code")]
    public string ZipCode { get; set; }

    [StringLength(5)]
    [Display(Name = "Zip Code Suffix")]
    public string ZipSuffix { get; set; }

    [StringLength(100)]
    [Display(Name = "Contact Name")]
    public string ContactName { get; set; }

    [EmailAddress, StringLength(50)]
    [Display(Name = "Contact Email")]
    public string ContactEmail { get; set; }

    [Display(Name = "Contact Phone"), DisplayFormat(DataFormatString = "{0:(###) ###-####}", ApplyFormatInEditMode = false)]
    public long? ContactPhone { get; set; }

    [Display(Name = "Contact Fax"), DisplayFormat(DataFormatString = "{0:(###) ###-####}", ApplyFormatInEditMode = false)]
    public long? ContactFax { get; set; }

    [StringLength(255)]
    public string Comment { get; set; }

    [Display(Name = "Responsible Employee")]
    public string EmployeeID { get; set; }

    /// <summary>
    /// This property is used for concurrency, to prevent two users from submitting conflicting updates.
    /// </summary>
    [Timestamp]
    public byte[] Timestamp { get; set; }
    #endregion

    #region Navigation Properties
    public virtual State State { get; set; }

    public virtual Country Country { get; set; }

    // THIS is where the FK Relationship issue lies.
    [ForeignKey("EmployeeID")]
    public virtual Employee ResponsibleEmployee { get; set; }
    #endregion
}

1 个答案:

答案 0 :(得分:1)

之前我遇到过这个问题。据我所知,你有两个选择

  • 为所有与虚拟数据没有关系的人编写值,并继续你正在做的事情。
  • 使用ModelState作为服务器端验证,以便在发布时强制执行此要求。