Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EF:即使在访问导航属性或删除虚拟关键字后,导航属性也为空_C#_.net_Asp.net Core_Entity Framework Core - Fatal编程技术网

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)