延迟加载的EF6实体停止工作

时间:2016-10-27 12:21:23

标签: c# .net entity-framework lazy-loading

我有一个用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。虽然这解决了问题,但它并没有解释为什么延迟加载在一段时间后停止工作。

0 个答案:

没有答案