0

EF4.3コードファーストデータベースからエンティティをロードする際に問題が発生しました。コードを次の実用的なサンプルコードに簡略化しました。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity.Infrastructure;

namespace CodeFirst {
    class Program {
        static void Main(string[] args) {
            Database.SetInitializer(new DropCreateDatabaseAlways<Context>());
            Database.DefaultConnectionFactory = new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0");

            using (Context context = new Context()) { 
                A a = new A { B = new B { Foo = 1 } };
                context.As.Add(a);
                context.SaveChanges();
                Print(context); // B has ID=1, Foo=1
            }

            using (Context context = new Context()) { 
                Print(context); // B is null
            }

            Console.ReadLine();
        }

        public static void Print(Context context) {
            A a = context.As.Single();
            Console.WriteLine("A: ID=" + a.Id);
            if (a.B == null) {
                Console.WriteLine("B: null");
            }
            else { 
                Console.WriteLine("B: ID=" + a.B.Id + ", Foo=" + a.B.Foo);
            }
        }
    }

    class Context : DbContext {
        public DbSet<A> As { get; set; }
    }

    class A {
        public int Id { get; set; }
        public B B { get; set; }
    }

    class B {
        public int Id { get; set; }
        public int Foo { get; set; }
    }
}

出力は次のとおりです。

A: ID=1
B: ID=1, Foo=1
A: ID=1
B: null

このサンプルコードでは、何らかの理由Aで新しいを取得するとContext、そのサブプロパティBnullです。ブレークポイントを設定し、がのポイントでデータベースに接続するBnull、すべてが正常に表示されます。

Table: A
--------
Id    B_Id
1     1

Table: B
--------
Id    Foo
1     1

私はコードファーストを学ぼうとしているだけなので、ここでひどい誤解があるかもしれませんが、これは私には非常に奇妙に思えます。誰かがこの振る舞いを説明できますか?

4

3 に答える 3

2

これまでに提供された両方の回答は、不必要に面倒です。

エンティティクラスを公開し、ナビゲーションプロパティをとして宣言するだけvirtualで、EFはそれらを遅延ロードします(つまり、オンデマンドで)

これDbContextを機能させるには、ナビゲーションプロパティにアクセスするときに、が開いている(つまり、破棄されていない)必要があります。

于 2012-08-23T01:33:25.910 に答える
0

それらを含める必要があります。

あなたはこのようなことをする必要があります:

var aWithNavProperties = As.Where(a=>a.Id==id).Include(a=>a.B).Single();
于 2012-08-22T21:05:20.763 に答える
0

デフォルトでは、Entity Frameworkは、明示的に指示された場合にのみテーブルを結合します(これは、ナビゲーションプロパティが通常maoする結合です)。Include()次の方法を使用できます。

var a = context.As.Include("B").Single();

エンティティ自体をロードした後にプロパティをロードすることもできます。これは、遅延読み込みパターンの実装です(注意して処理する必要があり、実際のP​​ITAにすることができます)

var a = context.As.Single();
// some other code
if (!a.BReference.IsLoaded())
    a.BReference.Load();
于 2012-08-22T21:08:52.590 に答える