3

私は単純なデータベーススキームを持っています:ユーザー、アカウント。ユーザーは、アカウントと 1 対多の関係にあります。

ado.net エンティティ データ モデルを生成しました。ユーザーとアカウントを作成し、それらをリンクすることもできます。データベースでは account.user_id が正しく入力されているため、理論的にはエンティティを介して C# で User.Account.ToList() にアクセスできるはずです。

ただし、 User.Account.ToList() にアクセスしようとすると、結果がゼロになります。

User user = db.User.First(U => U.id == 1);
List<Account> accounts = user.Account.ToList(); ##count = 0...

前のコードの前に次のコードを追加すると、突然正しいカウント 2 が表示されます。

 Account account1 = db.Account.First(A => A.id == 1);
 Account account2 = db.Account.First(A => A.id == 2);
 User user = db.User.First(U => U.id == 1);
 List<Account> accounts = user.Account.ToList(); ##count = 2...??

ここで何が欠けていますか??

4

3 に答える 3

2

はい、これは Entity フレームワークの使用を開始する際によくある問題です。親関係も子関係も遅延ロードされないため、明示的にロードする必要があります。クラス/メソッド間でオブジェクト コンテキストを共有する場合は、関係が既に読み込まれているかどうかを確認する必要があります。

例えば

    if(!user.Account.IsLoaded)
        user.Account.Load();

簡単な拡張メソッドを使用すると、これを簡単に行うことができます。

public static class EntityExtensions
{
    public static void EnsureLoaded(this RelatedEnd relatedEnd)
    {
        if (!relatedEnd.IsLoaded)
            relatedEnd.Load();
    }
}

これを使用すると、読み込み呼び出しが再び短くなります。

user.Account.EnsureLoaded();

また、エンティティ フレームワークの親子関係に共通の RelatedEnd を使用するため、これを親参照関係にも使用できます。

account.UserReference.EnsureLoaded();

rwwilden が言うように、この場合に常に子オブジェクトを親と共にロードする場合は、Include を使用して呼び出しをより効率化し、データベースへの余分なラウンドトリップを回避することをお勧めします。

于 2009-04-14T12:14:41.703 に答える
2

これにはObjectQuery.Includeメソッドを使用する必要があります。あなたの方法も機能しますが、追加のクエリが発生します。

あなたの例では、あなたは得るでしょう

User user = db.User.Include("Account").First(u => u.id == 1);

文字列"Account"が正しいかどうかを判断する必要があります。通常は、 のようなプレフィックスを付ける必要がありますMyEntities。これは、エンティティの名前空間に依存しますが、少し試行錯誤すれば、これを理解できるはずです。

于 2009-04-14T12:08:32.843 に答える
1

私の知識はフレームワークの少し小さいと思います。:)

関連するアカウントを最初に明示的に読み込む必要があります。

user.Account.Load();

正しく表示されるようになりました。

于 2009-04-14T11:53:02.850 に答える