2

我已经阅读了来自Ladislav的关于独立协会的文章。我已经检查了他在此链接中提供的信息。这些信息非常有帮助,并且提供了一些启示。但是,我想对我有权访问的现有数据库进行建模。它有三个表用户、证书和测验。

起初我认为建模是独立的关联。为什么?我的 Users 表有主键 UserID,Certificates 表有 PK CertID 和一个 UserID 列,我可以说它是外键。就在我认为它是一对多的关系时,我意识到用户表中的某些用户 ID 在证书表中找不到。但是,证书中的所有用户 ID 都可以在用户表中找到。

我的问题是我是否应该使用独立关联,如果是,如何实现这一点,使我的用户表成为主体类,而证书则成为依赖类。这样我就可以在我的用户表中显示或获取值,然后从我的 asp.net mvc 3 应用程序中的证书表中读取值。

请更正下面的代码,它显示了我打算实现我上面所说的内容:

   public class Certificates
{
   [Key]
    public Users CertID { get; set; }
    public int ID { get; set; }
    public DateTime  recvd { get; set; }
    public int QuizID { get; set; }


}

public class Users
{
    public int ID { get; set; }
    public string LastName { get; set; }
    public string FirstName { get; set; }
    public string email { get; set; }
    public ICollection<Certificates> Certificates { get; set; }
}

 public class Quiz
    {
        public int QuizID { get; set; }
        public string QuuizName { get; set; }
        public int VolumeNo { get; set; }
        public int  mark { get; set; }
        public ICollection<Certificates> Certificates { get; set; }
    }

public class cpdContext : DbContext
{
    public DbSet<Certificates> Certificates { get; set; }
    public DbSet<Users> Users { get; set; }
    public DbSet<Users> Quiz { get; set; }

最后,如何使用这三个类的信息显示详细信息视图,并能够添加用户标记和测试。我想建模的关系是测验和证书之间的一对多。

4

1 回答 1

2

我的 Users 表有主键 UserID,Certificates 表有 PK CertID 和一个 UserID 列,我可以说它是外键。就在我认为它是一对多的关系时,我意识到用户表中的某些用户 ID 在证书表中找不到。但是,证书中的所有用户 ID 都可以在用户表中找到。

这对于一对多的关系User来说是很正常的,在这种关系中,主体和Certificate从属关系,并且您对关系实施了约束。

我不认为这是决定独立或外键关联的论据。据我所知,您可以使用两种关联类型映射数据库模式。数据库模式不应该是决定的驱动因素。您链接的 Ladislav 的帖子详细解释了它。除了数据库模式之外,还有其他几点可以指导决策:

  • 架构:对象和关系世界的严格分离,这可能会导致您不希望将“外键”属性作为对象模型中的关系工件。这有利于独立协会。
  • 易用性:在某些情况下,额外的外键属性可以更轻松地处理关系,尤其是更新它们。这一点是针对外键关联的。
  • 性能:在某些情况下,具有较大模型的外键关联,EF 更快。

在大多数情况下,以上第 2 点为我个人提供了提示,但正如所说,两者都是可能的。

与外键关联的映射(我省略了除 PK、FK 和导航属性之外的所有属性以保持简短):

public class Certificates
{
    [Key]
    public int CertID { get; set; }

    [ForeignKey("User")]
    public int UserID { get; set; }
    [ForeignKey("Quiz")]
    public int QuizID { get; set; }

    public Users User { get; set; }
    public Quiz Quiz { get; set; }
}

public class Users
{
    public int ID { get; set; }
    public ICollection<Certificates> Certificates { get; set; }
}

public class Quiz
{
    public int QuizID { get; set; }
    public ICollection<Certificates> Certificates { get; set; }
}

这假定这两种关系都是必需的,即数据库中的 FK 不可为空。如果它们是,您还需要使 FK 属性为空(int?)。您可以使用 Fluent API 代替数据注释,类似于(但不完全相同!)以下示例。

与独立关联的映射:

public class Certificates
{
    [Key]
    public int CertID { get; set; }

    public Users User { get; set; }
    public Quiz Quiz { get; set; }
}

public class Users
{
    public int ID { get; set; }
    public ICollection<Certificates> Certificates { get; set; }
}

public class Quiz
{
    public int QuizID { get; set; }
    public ICollection<Certificates> Certificates { get; set; }
}

public class cpdContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entitiy<Users>()
            .HasMany(u => u.Certificates)
            .WithRequired(c => c.User)  // or WithOptional
            .Map(m => m.MapKey("UserID")); //<- DB FK column name

        modelBuilder.Entitiy<Quiz>()
            .HasMany(u => u.Certificates)
            .WithRequired(c => c.Quiz)  // or WithOptional
            .Map(m => m.MapKey("QuizID")); //<- DB FK column name
    }
}

中的导航属性Certificates不是必需的(第一个和第二个示例中都没有),您可以将它们删除,如果您不需要它们,只需使用无参数WithRequired()然后,并在第一个示例中使用 Fluent API。(可能对类中的集合的[ForeignKey("UserID")]注释也可以。)CertificatesUsers

于 2012-11-17T22:19:38.023 回答