2

Entity Framework 4.3.1を使用してC#でプロジェクトを作成するのはこれが初めてです。トーナメントテーブル、正確にはアドレスからすべてのデータを取得するのに問題があります。

まず、これが私のコードファーストコードです。これを実行すると、2つのテーブルが正しい関係で正しく作成されます。これらのクラスにはさらに多くの列が定義されていますが、この例ではいくつかしか示していません。

public class EFDbContext : DbContext
{
    public EFDbContext()
        : base("ApplicationServices")
    {
    }

    public DbSet<Tournament> tournaments { get; set; }
    public DbSet<Address> addresses { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }

    public class Tournament
    {
        [ScaffoldColumn(false)]
        public int TournamentId { get; set; }


        [Required(ErrorMessage="Tournament name is a required field")]
        public string Name { get; set; }


        [Required(ErrorMessage="Address is a required field")]
        public Address Address { get; set; }
    }

    public class Address
    {   
        [ScaffoldColumn(false)]
        public int AddressId { get; set; }


        [Required(ErrorMessage="Street name is a required field")]
        public string Street { get; set; }


        [Required(ErrorMessage="House number is a required field")]
        public string HouseNo { get; set; }
    }
}

アドレスを指定して新しいトーナメントを挿入し、データベースをチェックして、リレーションが使用されているかどうかを確認すると、それが機能していることがわかります。トーナメントには、新しく挿入されたアドレスを指すAddress_AddressId値があります。しかし、私がこれを行うことによって情報を取得しようとすると:

Tournament tournament = context.tournaments.Find(id);

デバッグすると、アドレスを除いて、トーナメントからのすべてのデータがトーナメントオブジェクトにあることがわかります。これはnullに設定されており、理由はまったくわかりません。

助けてくれませんか?

よろしくお願いします、バート

4

1 に答える 1

3

EntityFrameworkを使用して関連データをロードする方法を少し理解する必要があります。紹介はここにあります:http://blogs.msdn.com/b/adonet/archive/2011/01/31/using-dbcontext-in-ef-feature-ctp5-part-6-loading-related-entities.aspxこれらは、EntityFrameworkを効率的に操作するために知っておく必要のある基本です。

あなたが見ている振る舞いは予想されたものです。Entity Frameworkは、親エンティティをロードするだけの場合(例では)、ナビゲーションプロパティTournament.Addressを自動的にロードしません(例のように)。TournamentFind

関連データをロードするには、基本的に3つのオプションがあります。

  • 積極的な読み込み:

    Tournament tournament = context.tournaments
        .Include(t => t.Address) // <- "eager loading"
        .SingleOrDefault(t => t.TournamentId == id);
    

    トーナメントとアドレスは、単一のラウンドトリップとデータベースクエリでロードされます。

  • 遅延読み込み:ナビゲーションプロパティを次のようにマークしますvirtual

    public virtual Address Address { get; set; }
    

    TournamentEFは、トーナメントをロードすると、そのプロパティの1つにアクセスするとすぐに、関連するエンティティをロードできるプロキシオブジェクト(から派生)を動的に作成します。

    Tournament tournament = context.tournaments.Find(id);
    string street = tournament.Address.Street; // second query to DB happens here
    
  • 明示的な読み込み:

    Tournament tournament = context.tournaments.Find(id);
    context.Entry(tournament).Reference(t => t.Address).Load();
    // second query to DB happens here
    

    これは、データベースへの2つのクエリとラウンドトリップも必要であるため、遅延読み込みに似ていますが、Addressが読み込まれるタイミングを明示的に制御します。明示的な読み込みには、他の2つのオプションにはない関連データ(ナビゲーションコレクションの場合)をフィルタリングまたは並べ替えるオプションがあります。

于 2012-04-29T15:01:22.083 に答える