我已将以下属性设为true。
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; }
}
我正在从EF 6调用存储过程,如下所示:
public IEnumerable<User> GetUserDetails(int? userId)
{
var userIDParameter = userId.HasValue ?
new SqlParameter("@UserId", userId) :
new SqlParameter("@UserId", typeof(int));
return _dbContext.Database
.SqlQuery<User>("usp_GetUserDetails @UserId", userIDParameter);
}
在Controller中调用如下:
IEnumerable<User> user = _storedProcedureService.GetUserDetails(5);
在我的SP中,我的逻辑是:
Select * from User where UserId = @UserId
我获得与User
相关的所有数据,但UserRoles.Count
为零。
我做错了什么?
答案 0 :(得分:4)
在使用ADO.NET时,您询问是否使用了与实体框架的延迟加载。 ADO.NET不支持Lazy Loading,实体框架。
您的信息是ADO.NET;
var userIDParameter = userId.HasValue ?
new SqlParameter("@UserId", userId) :
new SqlParameter("@UserId", typeof(int));
return _dbContext.Database.SqlQuery<User>("usp_GetUserDetails @UserId", userIDParameter);
使用SqlParameter
之类的东西。
这是实体框架;
using (var db = new MyContext())
{
return db.User.Single(u => u.UserId = id);
}
或者,使用存储过程;
using (var db = new MyContext())
{
return db.GetUserDetails(id);
}
如果您想让Entity Framework处理存储过程和支持延迟加载,我建议您关注this tutorial。
答案 1 :(得分:1)
到目前为止,答案完全错过了标记。说实体框架方法(context.Database.SqlQuery<T>
)绕过实体框架或它是纯粹的ADO.Net是不正确的。
您使用SqlQuery<T>
。这与数据库优先方法不同,后者将存储过程导入EDMX。导入的存储过程由不同的方法执行:ExecuteFunction
。调用此方法并将结果映射到实体类型时,会发生在执行context.Database.SqlQuery<T>
时不会发生的两件事。
好的,两种不同的方法呈现不同的行为,为什么不呢?我可以忍受这个。唯一的事情(并且答案忽略了这一事实)是context.Database.SqlQuery<T>
在T
是实体类型时返回动态代理。 动态代理应该执行延迟加载。这是它所做的事情之一。所以对我来说意外的是,这两个陈述不会产生相同的结果:
var roles1 = _dbContext.Database.SqlQuery<User>(...).First().UserRoles;
var roles2 = _dbContext.Users.AsNoTracking().First(u => u.UserId == x).UserRoles;
只有第二个语句执行延迟加载,但都创建了一个代理User
实体。也许这是设计的。即便如此, 仍然令人困惑。
答案 2 :(得分:0)
您正在使用存储过程来检索绕过所有Entity Framework的用户对象,您将需要使用Entity Framework来检索您的用户以使Entity Framework完成其工作。如下所示。
_context.Set<Users>().Single(u=>u.UserId=5)
答案 3 :(得分:0)
原帖是正确的。 SQLQuery是一个EF方法,但它不返回支持延迟加载的对象。由于它使用反射将所选列返回到对象中,因此甚至可能无法设置对象键。在这种情况下,无法识别子对象。返回的对象不能像object.Parent.ID或object.Children.Count()一样使用。