1

了解しました。教師とアカウントの2つのモデルがあります。

public class Teacher : Person
{
    [Key]
    public Guid TeacherID { get; set; }

    public Guid? AccountID { get; set; }

    [Display(Name = "Hire Date")]
    [DataType(DataType.Date)]
    public DateTime? HireDate { get; set; }

    public virtual ICollection<Classroom> Classrooms { get; set; }

    public virtual Office Office { get; set; }

    public virtual Account Account { get; set; }
}

public class Account
{
    [Key]
    public Guid AccountID { get; set; }

    public Guid? TeacherID { get; set; }

    public String Username { get; set; }

    public String Salt { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public String SaltedPassword { get; set; }

    [Display(Name = "Secert Question")]
    public Guid SecertQuestionID { get; set; }

    [Display(Name = "Answer")]
    public String SecertAnswer { get; set; }

    public Guid RoleID { get; set; }

    public virtual SecertQuestion Question { get; set; }

    public virtual Role Role { get; set; }

    public virtual Teacher Teacher { get; set; }
}

GetAllクエリを実行すると:

public IEnumerable<Account> GetAll()
{
    return context.Accounts;
}

私のTeacherオブジェクトは、RoleやSecertQuestionオブジェクトのように入力されるのではなく、nullを返します。

2つのテーブルにTeacherIDとAccountIDのGUIDが同じであることを確認する偽のデータがあります。また、コンテキスト作成内で、このコードを使用してオプションの関係を作成しています。

modelBuilder.Entity<Account>()
    .HasOptional(a => a.Teacher)
    .WithOptionalDependent(a => a.Account);

これは正しいです?

だから私の質問は、オブジェクトアカウントに対してGetAll()を実行すると、Teacherオブジェクトがnullを返すのはなぜですか?アカウントオブジェクトにnull許容のTeacherオブジェクトが関連付けられているためですか?

アップデート:

したがって、データベースを分析した後、現在のマッピングで、AccountテーブルがTeacher_TeacherIDという新しい外部キーを作成していることに気付きました。TeacherとAccountの両方でナビゲーションマッピング(仮想オブジェクト)を保持しながら、これを修正するにはどうすればよいですか。

4

2 に答える 2

2

1 対 1 の関係をマッピングする正しいアプローチは次のようになります。

  • AccountIDからプロパティを削除しますTeacherTeacherは関係のプリンシパルであるため、依存関係への外部キーを持つことはできませんAccount

  • クラスTeacherIDからプロパティを削除します。Accountこの外部キーをモデル クラスで公開することはできません。(理由はわかりませんが、EF は慣例によりこのプロパティを外部キーとして認識せず、1 対 1 のマッピングにはHasForeignKey使用可能なメソッドがありません。)

したがって、次のようになります。

public class Teacher : Person
{
    [Key]
    public Guid TeacherID { get; set; }
    //...
    public string Name { get; set; }  // only for the test example below
    //...
    public virtual Account Account { get; set; }
}

public class Account
{
    [Key]
    public Guid AccountID { get; set; }
    //...
    public string Name { get; set; }  // only for the test example below
    //...
    public virtual Teacher Teacher { get; set; }
}

Fluent API を使用して外部キーをマップします。

modelBuilder.Entity<Account>()
    .HasOptional(a => a.Teacher)
    .WithOptionalDependent(a => a.Account)
    .Map(m => m.MapKey("TeacherID"));

TeacherIDこれにより、テーブルにnull 許容の外部キー列が作成されAccountます。

Teacherテーブルとテーブルに次の行がある場合Account...

1対1のデータ

...このクエリを実行できます...

var teacher = context.Teachers.First(t => t.Name == "Teacher 1");
var accountName = teacher.Account.Name;

...そして、ナビゲーション プロパティの遅延読み込みが成功したためaccountName、値が設定されます。"Account 1"teacher.Account

于 2012-09-17T20:11:26.097 に答える
0

デフォルトでは、ナビゲーション プロパティは入力されません。これは、大量のデータが誤って読み込まれるのを防ぐため、良いことです。

通常、遅延読み込みは、初めてアクセスしたときに開始され、教師を読み込みます。しかし、リポジトリ パターンを採用すると、この機能が失われます。

残っているのは、Eager ローディングを使用することです。

public IEnumerable<Account> GetAll() 
    { 
        return context.Accounts.Include(account=>account.Teacher); 
    } 

詳しい説明はこちらをご覧ください

于 2012-09-16T16:19:07.440 に答える