1

When a user gets to a location, he will get a question. As such, I have a class for "Questions" and a class for "Locations". When I retrieve a location, however, the Question parameter is always null. This seems to be a problem with the whole project, as the same problem repeats itself somewhere else (here, a "Game" has a list of "Teams", but the teams are always empty).

Objects are created when database is initialized:

public static void Initialize(DBContext context)
    {
        context.Database.EnsureCreated();
        if (!context.Games.Any())
        {
            var teams = new List<Team>();
            var team1 = new Team()
            {
                TeamName = "Kwizmasterz",
                TotalPoints = 0,
                TotalBoobyTraps = 2
            };
            var team2 = new Team()
            {
                TeamName = "Xesennettet",
                TotalPoints = 0,
                TotalBoobyTraps = 2
            };
            teams.Add(team1);
            teams.Add(team2);

            var game = new Game()
            {
                GameCode = "X35H0",
                team = teams
            };

            context.Games.Add(game);
            context.SaveChanges();
        }

        if (!context.Locations.Any())
        {
            var que = new Question()
            {
                QuestionText = "How much is 2 + 2?",
                Answer = "4",
                IsSolved = false,
                Points = 1000000
            };
            var loc = new Location()
            {
                LocationName = "LocationName",
                Latitude = 50.2299036,
                Longitude = 5.4163052,
                Question = que,
                IsBoobyTrapped = false
            };

            context.Locations.Add(loc);
            context.SaveChanges();
        }
    }

Location Class:

public class Location
{
    public int LocationID { get; set; }
    public string LocationName { get; set; }
    public double Latitude { get; set; }
    public double Longitude { get; set; }
    public Question Question { get; set; }
    public bool IsBoobyTrapped { get; set; }
    public int VictorTeamID { get; set; } = -1;
}

Question Class:

public class Question
{
    public int QuestionID { get; set; }
    public int QuestionType { get; set; } // 1 = Question - Answer

    public string QuestionText { get; set; }
    public int Points { get; set; }
    public bool IsSolved { get; set; }

    public string Answer { get; set; }
}

Controller Class:

[Route("api/v1")]
public class GameController : Controller
{
    private readonly DBContext context;
    public GameController(DBContext context)
    {
        this.context = context;
    }

    public IActionResult Index()
    {
        return View();
    }

    [Route("location")]
    [HttpPost]
    public IActionResult postGame([FromBody] Location newLocation)
    {
        newLocation.LocationID = context.Games.Count();
        context.Locations.Add(newLocation);

        return Created("", newLocation);
    }

    [Route("location")]
    [HttpGet]
    public List<Location> getLocations()
    {
        return context.Locations.ToList();
    }

    [Route("location/{id}")]
    [HttpGet]
    public Location getLocation(int id)
    {
        int _id = id - 1;
        List<Location> loc = context.Locations.ToList();
        if (loc[_id] != null)
            return loc[_id];
        else
            return null;
    }

    [Route("game")]
    [HttpPost]
    public IActionResult postGame([FromBody] Game newGame)
    {
        newGame.GameID = context.Games.Count();
        context.Games.Add(newGame);

        return Created("", newGame);
    }

    [Route("game")]
    [HttpGet]
    public List<Game> getGames()
    {
        return context.Games.ToList();
    }

    [Route("game/{id}")]
    [HttpGet]
    public Game getGame(int id)
    {
        List<Game> game = context.Games.ToList();
        if (game[id] != null)
            return game[id];
        else
            return null;
    }
}
3
  • "When I retrieve a location, however, the Question parameter is always null" - Where is your code that retrieves a location? It is not in the question at the moment. Please edit the question to show it. Commented Oct 26, 2018 at 13:10
  • Is it storing the question on question table correctly? if so probably your lazy load is disable, you must explicit include the question on your query... if you post your retrieve query will be easier to help :D Commented Oct 26, 2018 at 13:38
  • I just added the controller class. Commented Oct 27, 2018 at 12:57

1 Answer 1

2

This is because of lazy loading so objects stored in other tables won't load unless you include them. Link

You can do this by using Include("Question") so the complete syntax would be:

context.Locations.Include("Question") so you will include the question when retrieving the locations

You can do also multiple includes by chaining them context.Locations.Include("Question").Include("SomethingElse")

Edit as i see in your code getLocation still does not use the include. see below for the correct way to use it

public Location getLocation(int id)
{
    int _id = id - 1;
    List<Location> loc = context.Locations.Include("Question").ToList();
    if (loc[_id] != null)
        return loc[_id];
    else
        return null;
}

2nd edit Also i would rewrite getLocation because your pulling the whole list first and after getting the single location

public Location getLocation(int id)
{
    int _id = id - 1;
    //FirstOrDefault will return automatically a null if the id cannot be found. 
    //This will result in only getting the single Location from context instead the complete list
    return context.Locations.Include("Question").FirstOrDefault(x=>x.id == _id);
}
Sign up to request clarification or add additional context in comments.

6 Comments

I can't seem to find where to use the ".Include()" method is supposed to be called. I added my controller class at the end of the post.
Fixed it. I couldn't use ".Include()" because it didn't automatically include "using Microsoft.EntityFrameworkCore" at the top of the controller class.
@MyNameIsGuzse i edited and as i see your stil not using the include on correct spot
@MyNameIsGuzse also take al look at 2nd edit for doing it the cleaner way to not keep pulling all data from context instead of the single object you need
Everything is working, marked as the correct answer. Thank you so much!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.