5

私は現在、Code First アプローチを通じて Entity Framework (EF) を学習しています。新しく作成されたデータベース (つまり、EF によって作成されたデータベース) で、Professors とes の間の単純な 1 対多の関係をモデル化したいと考えています。Class

私のモデルでは、 a にesProfessorのコレクションがあります。ClassAClassには常に 1 がProfessor関連付けられています (つまり、対応するプロパティが null になることはありません)。Classおよび関連付けられた を作成して保存できますが、データベースから取得した のプロパティProfessorにアクセスすると、空になります。ただし、 から その への移動は可能です。ClassesProfessorClassProfessor

次のモデルを検討してください。

class Class
{
    public int Id { get; set; }
    public string Title { get; set; }
    public virtual Professor Professor { get; set; }
}

class Professor
{
    public int Id { get; set; }
    public string Name { get; set; }
    private ICollection<Class> classes = null;

    public virtual ICollection<Class> Classes
    {
        get { return classes ?? (classes = new HashSet<Class>()); }
        set { classes = value; }
    }
}

class ClassManager : DbContext
{
    public DbSet<Professor> Professors { get; set; }
    public DbSet<Class> Classes { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Class>().HasRequired(c => c.Professor);
    }
}

私の主な方法では、次のようにデータを作成してアクセスします。

    using (ClassManager db = new ClassManager())
    {
        Professor p = new Professor() { Name = "McTest" };
        Class c = new Class() { Title = "Testing Tests", Professor = p };

        p.Classes.Add(c);

        db.Professors.Add(p);
        db.Classes.Add(c);

        Console.WriteLine(db.SaveChanges() + " change(s) saved.");
    }

    using (ClassManager db = new ClassManager())
    {
        foreach (Professor p in db.Professors)
            Console.WriteLine("Prof. " + p.Name + " gives " + p.Classes.Count 
                + " classes.");

        foreach (Class c in db.Classes)
            Console.WriteLine(c.Title + " (Prof. " + c.Professor.Name + ")");
    }

出力は次のとおりです。

3 change(s) saved.
Prof. McTest gives 0 classes.
Testing Tests (Prof. McTest)

生成された DB スキーマは次のとおりです。

table Classes
    column Id (PK, int, not null)
    column Title (nvchar(max), null)
    column Professor_Id (FK, int, not null)
table Professors
    column Id (PK, int, not null)
    column Name (nvchar(max), null)

ご覧のとおり、Classesコレクション プロパティはスキーマのどこにも表示されません。それは意図したものですか?

誰かがこれに光を当てることができますか? 私が見つけたすべての例は、コレクションのプロパティについて詳しく説明していません。

4

2 に答える 2

10

わかりました、何時間も検索した後、解決策を見つけました。データベースにクエリを実行するときに、エンティティのコレクション プロパティを読み込むように EF に明示的に指示する必要があるようです。

foreach (Professor p in db.Professors.Include("Classes"))
    Console.WriteLine("Prof. " + p.Name + " gives " + p.Classes.Count
        + " classes.");

Includeメソッドはそれを行います。

于 2012-12-06T16:44:47.840 に答える
1

私のメインコードの2つの分離されたusingステートメントは意図的なものです。それらをマージすると、Classesプロパティが突然空になりませんが、その理由がわかりません。

2が1にマージされる場合は、データベースではなく、メモリに格納されているローカルエンティティを「クエリ」します。

professor最初のコンテキストでは、コンテキストにとの両方を追加する必要はありませんclass。教授を追加するだけで、classも保存されます。

DBスキーマをチェックし、エンティティがデータベースに適切にマップされていることを確認します。

最後に、Professorクラスをに変更します

class Professor
{
    public Professor()
    {
         Classes = new List<Class>();
    }

    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Class> Classes {get; set;}
}

遅延読み込みがハッシュセットを返すisnullロジックによって切り捨てられているのではないかと思います。

于 2012-12-06T13:37:57.577 に答える