我有一个用azure运行的web api。 api使用sql数据库,也在azure中运行。
api使用代码优先方法,让实体框架6.1.3构建数据库。一切都是延迟加载的,并且没有在任何实体上使用明确的急切加载。
这一直运作良好,但我们最近遇到了一个奇怪的问题,我们还没有找到原因。在部署api之后,它将在一段时间后,在访问相关实体时可能是几分钟,几小时或几天不加载相关实体。相反,所有相关实体都将 null 。需要注意的是,该系统仍在开发中,因此流量相当有限。
我们通常会注意到用户实体(用于执行登录),尽管我们已经在系统的其他部分看到了它。由于没有明确的原因,实体将突然在其所有相关实体表中开始为null。
我在问题发生时尝试调试azure api,实际上,从数据库检索的用户对象只有自己的数据集,所有相关的表都为null。一旦问题发生,唯一的解决方案是重新部署api,然后一切都开始工作,检索到的用户实体及其相关实体将再次都具有预期的数据。
问题发生时及之后数据库仍然相同。
这是我的用户业务实体:
public class User : BaseEntity
{
public int Id { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public virtual Person Person { get; set; }
}
要包含一个相关实体,这是Person businessentity:
public class Person : BaseEntity
{
public string PersonNumber { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int UserId { get; set; }
public virtual User User { get; set; }
}
我正在映射User实体,如下所示:
public class UserMap : EntityTypeConfiguration<User>
{
public UserMap()
{
//Key
HasKey(u => u.Id);
//table specific field settings
Property(u => u.Username).IsRequired();
Property(u => u.Password).IsRequired();
//table name
ToTable(nameof(User));
//relationship
HasOptional(u => u.Person)
.WithRequired(p =>p.User);
}
}
这是我使用用户名和密码从数据库中获取用户实体的地方:
User GetUser(string userName, string password)
{
var user = _context.User
.FirstOrDefault(x => x.Username.Equals(userName) && x.Password.Equals(password));
return user;
}
最后,我返回的用户实体用于使用加载的用户及其相关的enties(人等)设置身份。我不会得到任何名字,姓氏等因为我正面临的奇怪问题。
internal static void SetThreadIdentity(User user)
{
if (Thread.CurrentPrincipal.Identity.Name == string.Empty)
{
var identity = new BasicAuthenticationIdentity(
username: user.Username,
password: user.Password,
firstName: user.Person?.FirstName,
lastName: user.Person?.LastName,
personNumber: user.Person?.PersonNumber,
userId: user.Id);
var genericPrincipal = new GenericPrincipal(identity, null);
Thread.CurrentPrincipal = genericPrincipal;
}
}
解决方法是添加一堆.Include()调用以在我的GetUser方法中加载相关的enties。虽然这解决了问题,但它并没有解释为什么延迟加载在一段时间后停止工作。