AspNetUsers 主键上的"对象引用未设置为对象的实例"不一致



我们得到了经典的null引用异常,"对象引用未设置为对象的实例"。那里没有什么不寻常的,除了它是从上下文中直接出现的身份用户。

触发异常的线是:

allUsers.FirstOrDefault(u => u.Id == log.ActionByUserId)

,例外是在U.ID触发的。在这种情况下,您怎么会无效?这向我表明,Allusers中的一个条目是无效的,但是我不明白当通过实体框架从数据库中提取Allusers时会发生这种情况。这是在仅读取的控制器操作上发生的,因此我们没有尝试在请求中较早地创建用户。

此错误是在我们的生产实例上间歇性发生的,但是当我们将同一数据库还原为开发环境时不会发生。

有关上下文的更多代码(尽管我也将此代码简化为相关部分):

上下文(Applicationuser类具有其自身上下文,与大多数其他实体共享的上下文分开):

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection")
    {
    }
    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
}

服务:

public class UserService 
{
    private readonly ApplicationDbContext _context;
    public IEnumerable<ApplicationUser> GetUsers()
    {
        var contextUsers = _context.Users;
        return contextUsers;
    }
}

域对象

public class ApplicationUser : IdentityUser
{
    // Id is inherited from IdentityUser
}

控制器动作:

public ActionResult ParticipantLog(int participantId)
{
    var allUsers = UserService.GetUsers();
    var log = LogService.GetParticipantLog(participantId);
    var model = ParticipantLogsModelMapper.Create(log, allUsers);
}

mapper:

public static ParticipantLogsViewModel Create(ParticipantLog log, IEnumerable<ApplicationUser> allUsers)
{
    var actionBy = allUsers.FirstOrDefault(u => u.Id == log.ActionByUserId);
    var model = new ParticipantLogViewModel
    {
        ActionBy = actionBy.DisplayName
    };
    return model;
}

来自:

allUsers.FirstOrDefault(u => u.Id == log.ActionByUserId)

如果allUsers不包含任何记录,则返回default(T),在这种情况下为null

我整理了一个最小的控制台应用程序(提到Microsoft.AspNet.Identity.EntityFramework

static void Main(string[] args)
{
    var p = default(ApplicationUser);
}
public class ApplicationUser : IdentityUser
{
    // Id is inherited from IdentityUser
}

p确实是无效的。 FirstOrDefault扩展方法本质上将返回 IEnumerable中的 first 元素,或者如果列表中没有任何内容,则<T>的默认值,这似乎是在这种情况下发生的情况。

此错误是在我们的生产实例上间歇性发生的,但是当我们将同一数据库还原为开发环境时不会发生。

在简化了所显示的代码的地方,您是否省了一些错误检查/处理,导致A 失败尝试从数据库中检索用户详细信息,以返回空心集?这是您可能看到这里发生的情况的一种方式。

为了帮助缩小范围,在生产中,您可以在allUsers.FirstOrDefault调用上方放置一条诊断线,该诊断线检查allUsers.Any(),以确认allUsers中存在一些项目,然后尝试将其与您所拥有的任何其他诊断。开发环境的问题是,尽管它们很少能像生产一样多,但相比之下,它们通常具有很小的负载。这导致由于负载下运行而发生的问题只是没有被捡起=(

通过分析数据库服务器,我注意到问题行:

allUsers.FirstOrDefault(u => u.Id == log.ActionByUserId)

正在列举艾相物背后的整个桌子。我期望它只是为相关用户检索行。

我认为这是因为Allusers是IdentityUser对象,而不是标准EF域对象,而U.ID是Type type,而不是标准原始的对象。

我的解决方法是通过我的用户服务传递的ienumer,其中包括一种在usermanager上调用findbyid的方法

class UserService
{
    private readonly UserManager<ApplicationUser> _userManager;
    public UserService(ApplicationDbContext context)
    {
        _userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
    }
    public ApplicationUser Find(string userId)
    {
        return _userManager.FindById(userId);
    }
}

相关内容

  • 没有找到相关文章

最新更新