如何从EF Core建立的一对一关系中获取相关数据?
How to get related data from one to one relationship built by EF Core?
我有模型 class 继承自 IdentityUser
,它具有一对一的关系
public class CustomUser: IdentityUser
{
public ExtendedUserData ExtendedData { get; set; }
}
我有一个 ExtendedData 模型 class:
public class ExtendedUserData
{
public Guid Id { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public string Contract { get; set; }
public string ExtendedDataOfCustomUserId { get; set; }
public CustomUser CustomUser { get; set; }
}
(用 this EF core tutorial 制作)
但是,如果我使用这种方法获取数据
public ExtendedUserData GetExtendedUserDataById(Guid id)
{
return context.ExtendedUserDatas
.FirstOrDefault(x => x.ExtendedDataOfCustomUserId == id.ToString());
}
我试着这样制作
ExtendedUserData userData = new ExtendedUserData();
userData = GetExtendedUserDataById(id);
....
userData.CustomUser.Id;
或
userData.CustomUser.UserName;
我收到一个错误。像 NullRefExc
如何使用 1 对 1 关系从 ExtendedUserData
(或 mb CustomUser
)获取相关数据?
我想到了这个,但除此之外我没有想出任何其他的
public ExtendedUserData GetExtendedUserDataById(Guid id)
{
ExtendedUserData ud = context.ExtendedUserDatas
.FirstOrDefault(x => x.ExtendedDataOfCustomUserId == id.ToString());
ud.CustomUser = context.CustomUsers
.FirstOrDefault(x => x.Id == id.ToString());
return ud;
}
也许这可以做得更正确或更短?
感谢您的回答!
如果您已经加载了 CustomUser 并由 EF 跟踪,这应该可行。如果你只有身份证,你必须自己处理相关数据。几种方式:
使用预先加载
public ExtendedUserData GetExtendedUserDataById(Guid id)
{
return context.ExtendedUserDatas
.Include(x => x.CustomUser)
.FirstOrDefault(x => x.ExtendedDataOfCustomUserId == id.ToString())
;
}
当您知道每个消费者都希望加载 CustomUser 时很好。在一般的代码中,很难说出你需要提前包含什么(CustomUser 也可以有你可能想要加载的相关实体等等,导致 .Include(...).ThenInclude(...)
的长链)。
使用显式加载
public ExtendedUserData GetExtendedUserDataById(Guid id)
{
var user = context.ExtendedUserDatas
.FirstOrDefault(x => x.ExtendedDataOfCustomUserId == id.ToString())
;
if (user != null)
{
context.Entry(user).Reference(x => x.CustomUser).Load();
}
return user;
}
这并没有像写的那样有意义。但是由于任何人都可以做到这一点,因此您可以将加载相关数据的责任传递给更了解其需求的消费者。当关系链变长并包含集合时,写起来有点痛苦。
还有延迟加载隐藏了所有这些复杂性,但您必须采取一些步骤来激活它,如果您忘记了它的存在,它很容易扼杀您的性能。关于这三个的更多信息:https://docs.microsoft.com/en-us/ef/core/querying/related-data#lazy-loading
我有模型 class 继承自 IdentityUser
,它具有一对一的关系
public class CustomUser: IdentityUser
{
public ExtendedUserData ExtendedData { get; set; }
}
我有一个 ExtendedData 模型 class:
public class ExtendedUserData
{
public Guid Id { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public string Contract { get; set; }
public string ExtendedDataOfCustomUserId { get; set; }
public CustomUser CustomUser { get; set; }
}
(用 this EF core tutorial 制作)
但是,如果我使用这种方法获取数据
public ExtendedUserData GetExtendedUserDataById(Guid id)
{
return context.ExtendedUserDatas
.FirstOrDefault(x => x.ExtendedDataOfCustomUserId == id.ToString());
}
我试着这样制作
ExtendedUserData userData = new ExtendedUserData();
userData = GetExtendedUserDataById(id);
....
userData.CustomUser.Id;
或
userData.CustomUser.UserName;
我收到一个错误。像 NullRefExc
如何使用 1 对 1 关系从 ExtendedUserData
(或 mb CustomUser
)获取相关数据?
我想到了这个,但除此之外我没有想出任何其他的
public ExtendedUserData GetExtendedUserDataById(Guid id)
{
ExtendedUserData ud = context.ExtendedUserDatas
.FirstOrDefault(x => x.ExtendedDataOfCustomUserId == id.ToString());
ud.CustomUser = context.CustomUsers
.FirstOrDefault(x => x.Id == id.ToString());
return ud;
}
也许这可以做得更正确或更短?
感谢您的回答!
如果您已经加载了 CustomUser 并由 EF 跟踪,这应该可行。如果你只有身份证,你必须自己处理相关数据。几种方式:
使用预先加载
public ExtendedUserData GetExtendedUserDataById(Guid id)
{
return context.ExtendedUserDatas
.Include(x => x.CustomUser)
.FirstOrDefault(x => x.ExtendedDataOfCustomUserId == id.ToString())
;
}
当您知道每个消费者都希望加载 CustomUser 时很好。在一般的代码中,很难说出你需要提前包含什么(CustomUser 也可以有你可能想要加载的相关实体等等,导致 .Include(...).ThenInclude(...)
的长链)。
使用显式加载
public ExtendedUserData GetExtendedUserDataById(Guid id)
{
var user = context.ExtendedUserDatas
.FirstOrDefault(x => x.ExtendedDataOfCustomUserId == id.ToString())
;
if (user != null)
{
context.Entry(user).Reference(x => x.CustomUser).Load();
}
return user;
}
这并没有像写的那样有意义。但是由于任何人都可以做到这一点,因此您可以将加载相关数据的责任传递给更了解其需求的消费者。当关系链变长并包含集合时,写起来有点痛苦。
还有延迟加载隐藏了所有这些复杂性,但您必须采取一些步骤来激活它,如果您忘记了它的存在,它很容易扼杀您的性能。关于这三个的更多信息:https://docs.microsoft.com/en-us/ef/core/querying/related-data#lazy-loading