EF:导航属性即使在访问它或删除虚拟关键字后也为空

时间:2017-03-05 00:20:07

标签: c# .net asp.net-core entity-framework-core

我是实体框架(核心)的新手,我正面临着与延迟加载相关的一些问题。

我有以下具有一对一关系的简单数据模型:

User ----- AccessToken

用户:

public class User
{
    public int Id { get; set; }
    public string UserName { get; set; }

    public virtual AccessToken AccessToken { get; set; }
}

的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;

我还尝试从导航属性中删除virtual关键字,但没有成功。

有人会帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:2)

首先,这不是1:1的关系。对于数据库,可以有多个AccessToken具有相同的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都有一个与其User PK相同的PK,因此它的唯一绑定只有一个用户。

接下来,如评论中所述,EF核心尚不支持延迟加载。直到它(如果有的话)你必须使用Include(急切加载)......

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)

在后一种情况下,EF将通过 relationship fixup 连接用户及其令牌。