Home > Software engineering >  C#, ASP.NET MVC, Entity Framework : user.cart items are null
C#, ASP.NET MVC, Entity Framework : user.cart items are null

Time:01-16

I am using ASP.NET MVC with Entity Framework. I have a class that handles SQL called DataLayer.

There is a User object in the DataLayer.

I built a function that includes all the cart's items and returns the user by id, then makes the user in the datalayer as the found user (so it could log in).

The function code is:

public User userWithInclude(int? userId)
{
    List<User> users = Users.Include(x => x.Cart)
                            .Include(x => x.Cart.shakes)
                            .Include(x => x.Cart.equipmentList)
                            .Include(x => x.orders)
                            .Include(m => m.menus).ToList();

    User user = users.ToList().Find(x => x.ID == userId);

    return user;
}

Here's a snippet of the function the logs in :

public IActionResult LogInUser(User vm)
{
    User user = DataLayer.Data.Users.ToList()
                         .Find(x => x.userName == vm.userName && x.password == vm.password);

    if (user != null)
    {
        User user2 = DataLayer.Data.userWithInclude(user.ID);
        DataLayer.User = user2;

        if (user2.Cart == null)
        {
            user2.Cart = new Cart();
        }

        DataLayer.Data.SaveChanges();

        return RedirectToAction("Index");
    }
}

When I debug before the last line of the log in when I hover over the user object the cart's items all the vars exist but the object inside is null.

In the SQL Server database, the data exists with all the details.

How could it be?

CodePudding user response:

You can rewrite the get user class like this.

public User GetUserWithInclude(int? userId)
{
    return DataLayer.Data.Users.Include(x => x.Cart)
                            .Include(x => x.Cart.shakes)
                            .Include(x => x.Cart.equipmentList)
                            .Include(x => x.orders)
                            .Include(m => m.menus)
                            .FirstOrDefault(x => x.ID == userId);
}

Then your login actionresult can look like this

public IActionResult LogInUser(User vm)
{
    if(Login(vm.userName, vm.password)){
        return RedirectToAction("Index");
    }
    // handle login failure
}

Make a seperate loginMethod

public bool Login(string userName, string password)
{
    User user = DataLayer.Data.Users.FirstOrDefault(x => x.userName == userName && x.password == password);
    if (user != null)
    {
        User user2 = DataLayer.Data.GetUserWithInclude(user.ID);
        DataLayer.User = user2;

        if (user2.Cart == null)
        {
            user2.Cart = new Cart();
        }

        DataLayer.Data.SaveChanges();
        return true;
    }
    return false;
}

If this doesn't work you can try and get the cart after the user and debug if that's null, but I don't know enough about your foreign keys and relations etc to help you with that

CodePudding user response:

I think you must use ThenInclude() method.

For example:

public User GetUserWithInclude(int? userId)
  {
      return DataLayer.Data.Users.Include(x => x.Cart)                            
                        .ThenInclude(m=>m.shakes)
                        .Include(x=>x.Cart)
                        .ThenInclude(m => m.equipmentlist)
                        .Include(m=>m.Orders)
                        .Include(m => m.menus)
                        .FirstOrDefault(x => x.ID == userId);
  }
  • Related