3

我要让这变得非常简单。我有两张桌子。

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 关系共享主键的表。这些是否应该合并为一个,我不知道,我是基于现有的数据库。

现在,我遇到的问题是我何时访问它。

这段代码运行得很快(第二个,也许是两个):

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;
}

当我从用户表访问 UserProfile 时,为什么我的代码需要更长的时间?!

4

2 回答 2

10

可能是因为您在UserProfile这里延迟加载。这意味着对于循环中的每次迭代,UserProfile当您尝试访问电子邮件地址时,您都会单独调用数据库以加载。

我不确定您是如何创建userList集合的,但假设您正在对User表进行简单查询,您可以使用它Include来预先加载您希望预先拥有的任何属性:

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

现在,性能损失仅限于最初执行此查询时,枚举结果将不再需要单独调用数据库。

于 2012-09-07T16:53:15.980 回答
3

如果没有查询给您问题中的 s,很难确定User,但这就是我所看到的;

第一个查询循环遍历所有User对象并打印每个对象的名字。
1 SQL 查询。

第二个查询循环遍历所有User对象,并为每个对象发送一个查询到数据库以获取UserProfile对 EmailAddress 的访问权限。
401 次查询。

您应该阅读延迟加载与急切加载。

于 2012-09-07T16:54:45.403 回答