[英]Entity Framework Lazy Loading When Setting Properties
我有一个使用实体框架查询数据库并返回EF对象(ApplicationUser)的方法。 如果我有一个ApplicationUser的构造函数,尝试使用此方法填充其属性,那么设置该对象时,该对象的复杂属性会触发数据库被调用吗? 在原始对象中,它们是代理,因此将被延迟加载,但是仅将那些属性设置为同一对象的新实例的属性会调用数据库吗?
这是一个简单的例子:
public class ApplicationUser
{
public ApplicationUser(int userId)
{
ApplicationUser user = ApplicationUser.Select(userId);
this.FirstName = user.FirstName //this is fine
this.ApplicationRole = user.ApplicationRole //This is a complex object. Is it still going to be lazily loaded and called only if this.ApplicationRole is referenced?
}
public static ApplicationUser Select(int userId)
{
//this uses EF to return an Application User object
}
}
数据库将在以下行中调用:
this.ApplicationRole = user.ApplicationRole;
然后,将获取您的对象,并且不再延迟加载。
为确保发生这种情况,您必须进行一些配置:
必须启用延迟加载和代理创建:
public Context() : base("YourConnectionString") { Configuration.LazyLoadingEnabled = true; Configuration.ProxyCreationEnabled = true; }
导航属性必须声明为virutal
:
public class ApplicationUser { //... public virtual ApplicationRole ApplicationRole { get; set; } //... }
实际例子
假设您有这些课程
public class ApplicationUser
{
public int ApplicationUserId { get; set; }
public string FirstName { get; set; }
public virtual ApplicationRole ApplicationRole { get; set; }
public static Context db { get; set; }
public ApplicationUser()
{
}
public ApplicationUser(int userId)
{
ApplicationUser user = ApplicationUser.Select(userId);
this.FirstName = user.FirstName;
this.ApplicationRole = user.ApplicationRole; //database will be hit here
}
public static ApplicationUser Select(int userId)
{
//this uses EF to return an Application User object
return db.Users.Find(userId);
}
}
public class ApplicationRole
{
public int ApplicationRoleId { get; set;}
public string Name { get; set; }
}
第一击:
return db.Users.Find(userId);
生成的SQL:
SELECT
[Limit1].[ApplicationUserId] AS [ApplicationUserId],
[Limit1].[FirstName] AS [FirstName],
[Limit1].[ApplicationRole_ApplicationRoleId] AS [ApplicationRole_Application
RoleId]
FROM ( SELECT TOP (2)
[Extent1].[ApplicationUserId] AS [ApplicationUserId],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[ApplicationRole_ApplicationRoleId] AS [ApplicationRole_Applic
ationRoleId]
FROM [dbo].[ApplicationUsers] AS [Extent1]
WHERE [Extent1].[ApplicationUserId] = @p0
) AS [Limit1]
-- p0: '1' (Type = Int32)
第二击
this.ApplicationRole = user.ApplicationRole
生成的SQL
SELECT
[Extent2].[ApplicationRoleId] AS [ApplicationRoleId],
[Extent2].[Name] AS [Name]
FROM [dbo].[ApplicationUsers] AS [Extent1]
INNER JOIN [dbo].[ApplicationRoles] AS [Extent2] ON [Extent1].[ApplicationRo
le_ApplicationRoleId] = [Extent2].[ApplicationRoleId]
WHERE ([Extent1].[ApplicationRole_ApplicationRoleId] IS NOT NULL) AND ([Exte
nt1].[ApplicationUserId] = @EntityKeyValue1)
-- EntityKeyValue1: '1' (Type = Int32, IsNullable = false)
如果ApplicationRole
对象具有其他导航属性,则它们仍将被延迟加载,而不会出现问题。
这里有一个提示可能会有所帮助。 要查看EF何时访问数据库,请创建一个控制台应用程序,添加解决方案的引用,然后使用context.Database.Log
。 要查看有关日志记录的更多信息,请查看此链接https://msdn.microsoft.com/zh-cn/data/dn469464.aspx
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.