我要让它变得非常简单。我有两张桌子。
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时,为什么我的代码要花这么长时间?!
可能是因为您在此处延迟加载UserProfile
。这意味着,对于循环中的每个迭代,当您尝试访问电子邮件地址时,您都会单独调用DB以加载UserProfile
。
我不确定您是如何创建userList
集合的,但假设您对User
表进行简单查询,则可以使用Include
来预先加载您想要的任何属性:
var userList = (from u in dbContext.Users.Include("UserProfile")
select u)
现在,性能打击仅限于最初执行此查询时,对结果进行枚举将不再需要对DB进行单独调用。
如果没有问题中的User
,很难确定,但这就是我所看到的;
第一个查询循环遍历所有User
对象,并打印每个对象的FirstName
1个SQL查询
第二个查询在所有User
对象中循环,并为每个对象向数据库发送一个查询,以获取访问EmailAddress的UserProfile
401个查询
你应该仔细阅读懒惰加载和急切加载的对比。