C# 惰性加载在EntityFramework 6中不起作用
我已将以下属性设置为真C# 惰性加载在EntityFramework 6中不起作用,c#,entity-framework,lazy-loading,C#,Entity Framework,Lazy Loading,我已将以下属性设置为真 Configuration.LazyLoadingEnabled = true; Configuration.ProxyCreationEnabled = true; 我有两门课: public partial class User : BaseEntity { public User() { this.UserRoles = new List<UserRole>(); }
Configuration.LazyLoadingEnabled = true;
Configuration.ProxyCreationEnabled = true;
我有两门课:
public partial class User : BaseEntity
{
public User()
{
this.UserRoles = new List<UserRole>();
}
public int UserId { get; set; }
public string FirstName { get; set; }
public virtual ICollection<UserRole> UserRoles { get; set; }
}
public partial class UserRole : BaseEntity
{
public int UserRoleId { get; set; }
public int UserId { get; set; }
public int RoleId { get; set; }
public virtual User User { get; set; }
}
我得到了与User
相关的所有数据,但是UserRoles.Count
为零
我做错了什么?如果使用存储过程来检索用户对象,而这些对象绕过了所有实体框架,则需要使用实体框架来检索用户,以便实体框架完成其工作。类似下面的内容
_context.Set<Users>().Single(u=>u.UserId=5)
\u context.Set().Single(u=>u.UserId=5)
当您使用ADO.NET时,您正在询问如何使用实体框架的延迟加载。ADO.NET不支持延迟加载,实体框架支持
有关您的信息,请访问ADO.NET
var userIDParameter = userId.HasValue ?
new SqlParameter("@UserId", userId) :
new SqlParameter("@UserId", typeof(int));
return _dbContext.Database.SqlQuery<User>("usp_GetUserDetails @UserId", userIDParameter);
或者,使用存储过程
using (var db = new MyContext())
{
return db.GetUserDetails(id);
}
如果您想让Entity Framework处理存储过程并支持延迟加载,我建议您遵循。到目前为止的答案完全没有把握。说实体框架方法(
context.Database.SqlQuery
)绕过实体框架或者说它是纯ADO.Net是不正确的
您可以使用SqlQuery
。这与数据库优先方法不同,后者将存储过程导入EDMX。导入的存储过程由其他方法执行:。调用此方法并将结果映射到实体类型时,会发生两件在执行context.Database.SqlQuery
时不会发生的事情
context.Database.SqlQuery
在T
是实体类型时返回动态代理动态代理需要执行延迟加载。这是它的设计目标之一。因此,对我来说,这两个语句不会产生相同的结果是出乎意料的:
var roles1 = _dbContext.Database.SqlQuery<User>(...).First().UserRoles;
var roles2 = _dbContext.Users.AsNoTracking().First(u => u.UserId == x).UserRoles;
var roles1=_dbContext.Database.SqlQuery(…).First().UserRoles;
var roles2=_dbContext.Users.AsNoTracking().First(u=>u.UserId==x).UserRoles;
只有第二条语句执行延迟加载,但它们都创建一个代理
User
实体。也许这是故意的。即便如此,还是令人困惑。原来的帖子是正确的。SQLQuery是一个EF方法,但它不返回支持延迟加载的对象。由于它使用反射将所选列返回到对象中,因此甚至可能不会设置对象键。在这种情况下,无法识别子对象。返回的对象不能像object.Parent.ID或object.Children.Count()那样使用 我撤销了我的评论,因为这个线程说数据库类可能是在System.Data.Entity中定义的,它来自EF。它与ADO.Net有什么关系?在您展示的方法中,您没有使用存储过程,我需要使用SP.@user662285当使用SqlQuery()
时,您创建的原始查询不受上下文跟踪,因此不会延迟加载。我建议你也读书,随便什么。这不是纯粹的ADO.netDatabase.SqlQuery
甚至可以创建动态代理。它们只是不延迟加载,这是来自DbSet
s的其他代理所做的(即使没有跟踪)。我不完全确定,但我认为这在以前的EF版本中是有效的,因此这可能是一个bug或一个突破性的更改。@GertArnold存储过程使用延迟加载,而不是OP实现它的方式。也许您也应该阅读本教程?选择将DbContext
exposeDatabase
作为公共财产造成了如此多的损害和混乱。。。对于熟悉ADO.NET及其SqlQuery
的开发人员来说,这种诱惑已经使许多人误入歧途。
var userIDParameter = userId.HasValue ?
new SqlParameter("@UserId", userId) :
new SqlParameter("@UserId", typeof(int));
return _dbContext.Database.SqlQuery<User>("usp_GetUserDetails @UserId", userIDParameter);
using (var db = new MyContext())
{
return db.User.Single(u => u.UserId = id);
}
using (var db = new MyContext())
{
return db.GetUserDetails(id);
}
var roles1 = _dbContext.Database.SqlQuery<User>(...).First().UserRoles;
var roles2 = _dbContext.Users.AsNoTracking().First(u => u.UserId == x).UserRoles;