(MVC3 /实体框架)如何在使用候选键作为外键的数据库中执行CRUD操作

时间:2013-04-30 13:38:01

标签: asp.net-mvc entity-framework database-first candidate-key

我是MVC3和Web开发的完全初学者。

我的客户端数据库使用一个表的唯一候选键作为另一个表的外键。我无法改变数据库的设计方式。我有从数据库表派生的模型。我知道Entity Framework不支持候选键作为另一个表的外键。

所以我的问题是,专业人士如何解决实体框架的这种限制?

1 个答案:

答案 0 :(得分:0)

由于EF的当前版本要求FK指向PK,因此这不是一个容易解决的问题。

我使用过的一种技术(使用EF CodeFirst ......呃......第二次)覆盖父表映射中的PKEY并改为指定匿名类型。

public class ParentObject
{
    public int Id {get; set;}  //the actual PKEY in the Db
    public string CandidateKey1 {get;set;}
    public string CandidateKey2 {get;set;}
    public string CandidateKey3 {get;set;}

    public virtual ICollection<ChildObject> ChildObjects {get;set;}
}

public class ChildObject
{
    public int Id {get; set;} 
    public string CandidateKey1 {get;set;}
    public string CandidateKey2 {get;set;}
    public string CandidateKey3 {get;set;}

    public virtual ParentObject ParentObject {get;set;}
}

为了使其正常工作,您需要指定Parent表的PKEY是匿名对象,而不是实际存储在DB中的PKEY。

public ParentObjectMap()
{
    // Primary Key
    //this.HasKey(t => t.Id); //override this as PKEY for EF purposes
    this.HasKey(t => new { t.CandidateKey1, t.CandidateKey2, t.CandidateKey3 });

    // Table & Column Mappings
    this.ToTable("ParentTable");
    this.Property(t => t.Id).HasColumnName("ParentId");
    this.Property(t => t.CandidateKey1).HasColumnName("Key1");
    this.Property(t => t.CandidateKey2).HasColumnName("Key2");
    this.Property(t => t.CandidateKey3).HasColumnName("Key3");
}

和子对象图

public ChildObjectMap()
{
    // Primary Key
    this.HasKey(t => t.Id); 

    // Table & Column Mappings
    this.ToTable("ChildTable");
    this.Property(t => t.Id).HasColumnName("ChildId");
    this.Property(t => t.CandidateKey1).HasColumnName("Key1");
    this.Property(t => t.CandidateKey2).HasColumnName("Key2");
    this.Property(t => t.CandidateKey3).HasColumnName("Key3");

    this.HasRequired(t => t.ParentObject)
        .WithMany(t => t.ChildObjects)
        .HasForeignKey(t => new { t.CandidateKey1, t.CandidateKey2, t.CandidateKey3 });
}

当然,这会引入其他问题,例如您在实现的代码中需要处理的实际Parent Id属性的唯一性。然而,当针对类似的(候选键控)Progress 4GL OpenEdge编写代码时,这种技术已经完成了我的工作 - &gt;我无法控制的MSSQL数据库。

它也没有原生EF那么快 - &gt; MSSQL映射利用数据库中的FK关系。