【问题标题】:( MVC3/Entity Framework) How to perform CRUD operation in a database that uses Candidate keys as foreign keys(MVC3/Entity Framework) 如何在使用候选键作为外键的数据库中执行 CRUD 操作
【发布时间】:2013-04-30 13:38:00
【问题描述】:

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

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

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

【问题讨论】:

  • 对不起,我忘了说每个表都有一个主键和一个或多个候选键。正是这些候选键被相关表用作外键。

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


【解决方案1】:

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

我使用的一种技术是(使用 EF CodeFirst...er...Second)覆盖父表映射中的 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 -> MSSQL db 编写代码时,这种技术已经为我完成了工作,而我无法控制。

它也不如原生 EF -> 利用数据库中的 FK 关系的 MSSQL 映射快。

【讨论】:

  • 截至 2011 年,Microsoft 正在解决这个问题(“唯一性约束”),但更新的博客文章显示它已从 EF 5 推迟。blogs.msdn.com/b/efdesign/archive/2011/03/09/…
  • 感谢您的回答。我会试试的。我最初的工作是将这些表视为单独的未连接表,然后使用 AJAX 和 LINQ 使用 where 子句提取数据,但我不喜欢这个想法。
猜你喜欢
  • 2013-03-06
  • 2016-05-28
  • 1970-01-01
  • 1970-01-01
  • 2022-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-09
相关资源
最近更新 更多