C# EF:即使在访问导航属性或删除虚拟关键字后,导航属性也为空
我不熟悉实体框架(核心),正如我所想,我面临一些与延迟加载相关的问题 我有以下一对一关系的简单数据模型:C# EF:即使在访问导航属性或删除虚拟关键字后,导航属性也为空,c#,.net,asp.net-core,entity-framework-core,C#,.net,Asp.net Core,Entity Framework Core,我不熟悉实体框架(核心),正如我所想,我面临一些与延迟加载相关的问题 我有以下一对一关系的简单数据模型: User ----- AccessToken 用户: AccessToken: public class AccessToken { public int Id { get; set; } public string Token { get; set; } [ForeignKey("User"), Required] public int UserId {
User ----- AccessToken
用户:
AccessToken:
public class AccessToken
{
public int Id { get; set; }
public string Token { get; set; }
[ForeignKey("User"), Required]
public int UserId { get; set; }
public virtual User User { get; set; }
}
现在,当我尝试使用用户的导航属性获取用户的AccessToken时,它总是null:
var t1 = Context.Find<User>(user.Id);
var t2 = t1.AccessToken;
var t3 = Context.Find<User>(user.Id).AccessToken;
var t1=Context.Find(user.Id);
var t2=t1.0;
var t3=Context.Find(user.Id).AccessToken;
我还试图从导航属性中删除virtual
关键字,但没有成功
有人能帮我解决这个问题吗?首先,这不是一对一的关系。对于数据库,可以有多个
AccessToken
s具有相同的UserId
,即它是1:n关系。要将其转化为真正的1:1关系,您的模型应如下所示:
public class User
{
public int Id { get; set; }
public string UserName { get; set; }
public virtual AccessToken AccessToken { get; set; }
}
public class AccessToken
{
[ForeignKey("User")]
public int Id { get; set; }
public string Token { get; set; }
public virtual User User { get; set; }
}
现在,任何AccessToken
都将有一个与用户的PK相同的PK,因此它是唯一的,并且只绑定到一个用户
接下来,正如评论中所说,EF核心中还不支持延迟加载。直到它(如果有的话)你必须使用包含(急切加载)
。。。或单独加载数据(电子合法加载):
在后一种情况下,EF将通过关系修复连接用户及其令牌。首先,这不是1:1关系。对于数据库,可以有多个AccessToken
s具有相同的UserId
,即它是1:n关系。要将其转化为真正的1:1关系,您的模型应如下所示:
public class User
{
public int Id { get; set; }
public string UserName { get; set; }
public virtual AccessToken AccessToken { get; set; }
}
public class AccessToken
{
[ForeignKey("User")]
public int Id { get; set; }
public string Token { get; set; }
public virtual User User { get; set; }
}
现在,任何AccessToken
都将有一个与用户的PK相同的PK,因此它是唯一的,并且只绑定到一个用户
接下来,正如评论中所说,EF核心中还不支持延迟加载。直到它(如果有的话)你必须使用包含(急切加载)
。。。或单独加载数据(电子合法加载):
在后一种情况下,EF将通过关系修复连接用户及其令牌。您是否使用EF Core?(我看到您的问题被标记为EF6,但我仍然相信您使用的是Core)EF Core还不支持延迟加载,请参阅。请使用搜索,这是48小时内的第二个或第三个问题hours@Tseng好的,我需要使用include。谢谢。好的。microsoft提到:Entity Framework Core将自动修复以前加载到上下文实例中的任何其他实体的导航属性。因此,即使没有明确包含导航属性的数据,如果以前加载了部分或所有相关实体,也可能会填充该属性。
,但实际上没有发生这种情况!如果我理解正确的话。在示例代码中,您从未加载过AccessToken
。他们说EntityFrameworkCore将自动修复以前加载到上下文实例中的任何其他实体的导航属性。您的AccessToken
以前没有加载到上下文中,这就是它无法正常工作的原因。是的,文档在它上面很清楚:context.Entry(blog.Collection)(b=>b.Posts.Load()代码>您正在使用EF Core吗?(我看到您的问题被标记为EF6,但我仍然相信您使用的是Core)EF Core还不支持延迟加载,请参阅。请使用搜索,这是48小时内的第二个或第三个问题hours@Tseng好的,我需要使用include。谢谢。好的。microsoft提到:Entity Framework Core将自动修复以前加载到上下文实例中的任何其他实体的导航属性。因此,即使没有明确包含导航属性的数据,如果以前加载了部分或所有相关实体,也可能会填充该属性。
,但实际上没有发生这种情况!如果我理解正确的话。在示例代码中,您从未加载过AccessToken
。他们说EntityFrameworkCore将自动修复以前加载到上下文实例中的任何其他实体的导航属性。您的AccessToken
以前没有加载到上下文中,这就是它无法正常工作的原因。是的,文档在它上面很清楚:context.Entry(blog.Collection)(b=>b.Posts.Load()代码>实际操作设置是EF核心改进的一对一(一:)。这是一个具有唯一约束的FK。当然,剩下的部分你是对的。这正是我现在正在做的(使用include),但这使得在每次需要加载不同数量的导航属性时,使用存储库和工作单元模式几乎是不可能的(例如,有时没有导航属性,有时为1,另一次为4,等等),在这种情况下,我找不到为这种情况编写任何通用的有用存储库的方法。。。我希望支持懒惰加载再次很快。。。顺便说一句,这个Dumb()函数是什么?@Ivan我尝试了UserId
字段。我看到了EF6的不同之处,但没有意识到它实际上是1:1。即使如此,我想我还是希望数据库模式本身也能强制执行它(即尽可能多地执行)。顺便说一句,我最近开始对ef core很满意了。@MohammedNoureldin Dump来自Linqpad。我把它拿走了。关于你的担忧,这就是我一直在说的架构:架构应该是有用的。我见过太多的UoW/存储库实现已经成为一件棘手的事情。通常这意味着存储库负责一个实体,涉及多个实体的每个操作(对象图)都会引发责任问题。阅读也一样。使用EF,您应该能够从数据库中读取丰富的对象图。如果体系结构不允许,请修改它,或者干脆放弃它。使用您的存储库,可以为属性添加参数为Include
d的方法
using (var db = new MyContext())
{
var user = db.Users.Include(u => u.AccessToken)
.Single(u => u.Id == 1);
}
db.AccessTokens.Where(a => a.Id == 1).Load();
var user = db.Users
.Single(u => u.Id == 1); // Or db.Users.Find(1)