2

Ladislavの Independent Association に関する記事を読みました。彼がこのリンクで提供した情報を確認しました。情報は非常に役に立ち、光を当てます。ただし、アクセス権を与えられた既存のデータベースをモデル化したいと考えています。これには、 Users 、 Certificates 、および Quiz という 3 つのテーブルがあります。

最初は、モデリングは独立した協会だと思っていました。なんで?私のUsersテーブルには主キーのUserIDがあり、CertificatesテーブルにはPK CertIDと、外部キーと言える列UserIDがあります。1 対多の関係だと思ったときに、Users テーブルの一部の UserID が Certificates テーブルにないことに気付きました。ただし、証明書内のすべての UserID は、Users テーブルで見つけることができます。

私の質問は、独立した関連付けを使用する必要があるかどうかです。そうであれば、Users テーブルがプリンシパル クラスになり、Certificates が従属クラスになるようにする方法です。これは、Users テーブルの値を表示または取得し、asp.net mvc 3 アプリケーションの Certificate テーブルから値を読み取ることができるようにするためです。

上記のことを達成しようとしていることを示す以下のコードを修正してください。

   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; }

最後に、これら 3 つのクラスからの情報を含む詳細ビューを表示して、ユーザー マークとテストを追加する方法を教えてください。私がモデル化したい関係は、クイズと証明書の間の 1 対多です。

4

1 に答える 1

2

私のUsersテーブルには主キーのUserIDがあり、CertificatesテーブルにはPK CertIDと、外部キーと言える列UserIDがあります。1 対多の関係だと思ったときに、Users テーブルの一部の UserID が Certificates テーブルにないことに気付きました。ただし、証明書内のすべての UserID は、Users テーブルで見つけることができます。

Userこれは、プリンシパルと従属関係である 1 対多の関係ではごく普通のことであり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 が null 可能でないことを前提としています。その場合は、FK プロパティも null 可能にする必要があります ( 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は必要ありません (最初の例でも 2 番目の例でもありません)。不要な場合は削除できます。必要がない場合は、パラメーターなしWithRequired()を使用し、最初の例で Fluent API を使用します。(おそらく、クラス内のコレクションの[ForeignKey("UserID")]注釈も同様に機能します。)CertificatesUsers

于 2012-11-17T22:19:38.023 に答える