31

私は2つのオブジェクトクラスを持っています

public class User
{
    public Guid Id { get; set; }
    public string Name { get; set; }

    // Navigation
    public ICollection<Product> Products { get; set; }
}

public class Product
{
    public Guid Id { get; set; }

    // Navigation
    public User User { get; set; }
    public Guid User_Id { get; set; }

    public string Name { get; set; }
}

dataContextを使用してユーザーをロードすると、製品のリストがnullになります(これは問題ありません)。

製品リストに「仮想」キーワードを追加すると、

public virtual ICollection<Product> Products { get; set; }

ユーザーをロードすると、製品リストも表示されます。

なぜこうなった?これを明示しない限り、エンティティをロードしないために「virtual」キーワードが使用されると思いました(「Include」ステートメントを使用)

私はそれをすべて間違ったと思います

4

2 に答える 2

67

これは間違っています

「virtual」キーワードは、これを明示しない限り (「Include」ステートメントを使用して) エンティティをロードしないために使用されます。

遅延読み込みとは、コレクションまたはナビゲーション プロパティに最初にアクセスしたときにエンティティが自動的に読み込まれることを意味し、エンティティが常に親オブジェクトと共に読み込まれたかのように透過的に行われます。

「include」を使用すると、クエリするプロパティを指定するときにオンデマンドで読み込まれます。

キーワードの存在はvirtual、遅延読み込みのみに関連しています。virtualキーワードにより、エンティティ フレームワーク ランタイムがエンティティ クラスとそのプロパティの動的プロキシを作成できるようになり、それによって遅延読み込みがサポートされます。仮想がない場合、遅延読み込みはサポートされず、コレクション プロパティで null が返されます。

実際には、どのような場合でも "include" を使用できますが、コレクションおよびナビゲーション プロパティにアクセスする唯一の方法は、遅延読み込みを行わないことです。

于 2012-07-13T11:27:39.607 に答える
4

ef コンテキストいる間、遅延ロードの対象となるプロパティを探していると思います。

using (var db = new Context())
{
    var user = db.Users.Where(...);

    var products = user.Products; // being loaded right away
}

それを残してみてください:

User user;
using (var db = new Context())
{
    user = db.Users.Where(...);

    // I guess you will need here:
    // .Include(u => u.Products)
}
var products = user.Products; // what error will you get here?
于 2012-07-13T11:24:59.577 に答える