为了账号安全,请及时绑定邮箱和手机立即绑定

查询数据库,列值为空?

查询数据库,列值为空?

C#
莫回无 2023-07-09 10:22:29
我有一个用户登录然后它调用控制器。我在用户表中搜索电子邮件匹配并将其保存到用户变量中。但是当我尝试检查它是否是管理员用户时,权限列为空,它是空引用。为什么用户不首先或默认提取所有列数据,我检查数据库并且permissionId在那里,但是当我检查所述行的值时将其拉为空。我真的很清楚,这是我的第一个更大的项目,也是我第一次似乎无法在谷歌上找到答案。这是实体:用户:public class User    {        public int    UserId        { get; set; }        [Column(TypeName = "VARCHAR(100)")]        [StringLength(100)]        [Required]        public string FirstName     { get; set; }        [Column(TypeName = "VARCHAR(100)")]        [StringLength(100)]        [Required]        public string LastName      { get; set; }        [Column(TypeName = "VARCHAR(100)")]        [StringLength(250)]        [Required]        public string Email         { get; set; }        [Required]        public string Password      { get; set; }        [Required]        public string UserName      { get; set; }        //The user can have many posts         public List<Post> Post      { get; set; }        public virtual Permissions Permissions { get; set; }    }权限:public class Permissions    {        public int PermissionsID {get; set;}        [Required]        public bool admin { get; set; }        [Required]        public bool StandUser { get; set; }        //Many Users can have a permission, this makes the foreign key for the Post Table.        public List<User> User { get; set; }    }这是登录后控制器:[HttpPost]        public IActionResult Login(LoginViewModel loginViewModel)        {            //We're grabbing the plain text password so we can hash it later.             loginViewModel.plainTextPassword = loginViewModel.user.Password;            //Searching for the users emaill address and gathering the user information.             User userInfo = _context.Users.FirstOrDefault(x => x.Email == loginViewModel.user.Email);我希望 userInfo 的所有行都不为空,以便稍后我可以检查用户是否是管理员。
查看完整描述

1 回答

?
qq_笑_17

TA贡献1818条经验 获得超7个赞

通常,延迟加载会在幕后处理此问题,但如果您没有启用或可用(EF Core 2.1 之前的版本),您将留下 #null 引用。


选项:


1) 预加载权限.Include(x => x.Permissions)。


正如法比奥上面评论的那样,这应该可以解决您眼前的问题。急切加载的考虑因素是您必须显式包含您想要引用的所有内容,这可能意味着加载比您需要的更多的数据。


2)用于Select获取您需要的数据。


通过利用,Select您可以消除对急切加载或延迟加载命中的担忧,并生成经过优化以仅返回您关心的数据的 SQL。如果您想要根据数据状态执行某些逻辑,您可以使用匿名类型来表示数据。在其他情况下,您想要将数据返回到视图,请使用 Select (或 Automapper 的ProjectTo)来填充视图模型。


例如:


[HttpPost]

public IActionResult Login(LoginViewModel loginViewModel)

{

    loginViewModel.plainTextPassword = loginViewModel.user.Password;


    var userInfo = _context.Users.Where(x => x.Email == loginViewModel.user.Email)

        .Select(x => new 

        {

            x.UserId,

            x.FirstName,

            x.LastName,

            x.Password,

            IsAdmin = x.Permissions.Admin

        }).SingleOrDefault();


    if (userInfo == null)

    {

        ViewBag.Error = "Sorry, but we couldn't log you in.";

        return View();

    }

    else if (Hashing.Confirm(loginViewModel.plainTextPassword, userInfo.Password, Supported_Ha.SHA256))

    {

        HttpContext.Session.SetString("UserFirstName", userInfo.FirstName);

        HttpContext.Session.SetString("UserLastName", userInfo.LastName);

        HttpContext.Session.SetInt32("UserUserId", userInfo.UserId);



        HttpContext.Session.SetString("IsAdmin", userInfo.IsAdmin.ToString());


        ViewBag.IsAdmin = userInfo.IsAdmin.ToString();

        ViewBag.SessionUserName = userInfo.FirstName;

        return RedirectToAction("Index");

    }

    ViewBag.Error = "Sorry, but we couldn't log you in.";

    return View("Index");

}

主题演讲:我们使用 Select 只检索我们需要的用户列(名称、ID、密码哈希)以及权限引用中的“admin”标志。它被加载到一个临时容器中,我们可以在此方法中引用它。每当您需要单行而不是/时,最好使用Single/ ,因为可以屏蔽意外的重复数据场景。IMO /切勿在没有子句的情况下使用,以确保结果一致。SingleOrDefaultFirstFirstOrDefaultFirstFirstOrDefaultOrderBy


查看完整回答
反对 回复 2023-07-09
  • 1 回答
  • 0 关注
  • 100 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信