3

これを本当にシンプルにします。私は2つのテーブルを持っています。

public class User
{
    public virtual int UserId { get; set; } //primary key AND foreign key
    //user attributes in here
    public virtual UserProfile UserProfile { get; set; }
}
public class UserProfile
{
    public virtual int UserId { get; set; } //primary key AND foreign key
    //profile attributes in here
    public virtual User User { get; set; }
}

基本的に、それらは 1 対 1 の関係で主キーを共有する 2 つのテーブルです。これらを 1 つに結合する必要があるかどうかはわかりませんが、これは既存のデータベースに基づいています。

さて、私が抱えている問題は、アクセスするときです。

このコードは速くなります (2 番目、おそらく 2 番目):

List<User> userList; //**This userList is defined elsewhere, but it's a list of about 400 users.
foreach (User user in userList)
{
    var test = user.FirstName;
}

このコードは非常に遅くなります (10 ~ 30 秒):

List<User> userList; //**This userList is defined elsewhere, but it's a list of about 400 users.
foreach (User user in userList)
{
    var test = user.UserProfile.EmailAddress;
}

user テーブルから UserProfile にアクセスすると、コードの実行に時間がかかるのはなぜですか?!

4

2 に答える 2

10

おそらく、UserProfileここで遅延読み込みを行っているためです。これは、ループ内の反復ごとにUserProfile、電子メール アドレスにアクセスしようとしたときに DB を個別に呼び出してロードすることを意味します。

コレクションをどのように作成しているかはわかりませんが、テーブルuserListに対して単純なクエリを実行していると仮定すると、事前に必要なプロパティを積極的にロードするために使用できます。UserInclude

var userList = (from u in dbContext.Users.Include("UserProfile")
                select u)

これで、パフォーマンス ヒットは、このクエリが最初に実行されたときに制限され、結果を列挙するために DB を個別に呼び出す必要がなくなりました。

于 2012-09-07T16:53:15.980 に答える
3

クエリUserで質問の s が表示されない限り、確実に知ることは困難ですが、これが私が見ているものです。

最初のクエリは、すべてのUserオブジェクトをループして、それぞれの FirstName を出力します。
1 SQL クエリ。

2 番目のクエリは、すべてのオブジェクトをループしUser、各オブジェクトに対してデータベースにクエリを送信しUserProfileて、EmailAddress へのアクセスを取得します。
401 クエリ。

遅延読み込みと熱心な読み込みについて読む必要があります。

于 2012-09-07T16:54:45.403 に答える