我是实体框架(核心)的新手,我正面临着与延迟加载相关的一些问题。
我有以下具有一对一关系的简单数据模型:
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
关键字,但没有成功。
有人会帮我解决这个问题吗?
答案 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 连接用户及其令牌。