Search code examples
c#sql-serverdatabaset-sqlconnection

DB Context is null when running program


I have been struggling with this for half a day. I cannot get the context to work in my application when connecting to my DB. I can connect to the DB just fine if I want to add/remove dbsets, but I cannot figure out what is wrong with my dbcontext located in the SelectCharacter file.

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;

namespace HeroesDB
{
    public class HeroesDBContext : DbContext
    {
        public static DbSet<HeroModels.Mage> Mages { get; set; }
        public static DbSet<HeroModels.Archer> Archers { get; set; }
        public static DbSet<HeroModels.Weapon> Weapons { get; set; }
        public static DbSet<HeroModels.Food> Foods { get; set; }
        public DbSet<UserRegistration.UserController> Users { get; set; }

        public HeroesDBContext()
        {

        }

        public HeroesDBContext(DbContextOptions options)
            : base(options)
        {

        }

        //add to allow migrations when the context is not built
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                var builder = new ConfigurationBuilder()
                    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

                var config = builder.Build();
                var cnstr = config["ConnectionStrings:HeroesDB"];
                var options = new DbContextOptionsBuilder<HeroesDBContext>().UseSqlServer(cnstr);
                optionsBuilder.UseSqlServer(cnstr);
            }
        }
    }
}
using Microsoft.Extensions.Configuration;

namespace Heroes
{
    public static class Program
    {
        public static IConfigurationRoot _configuration;

        /// <summary>
        ///  The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {

            var builder = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
            _configuration = builder.Build();


            SelectCharacter.CharacterSelection();
            Adventure.AdventureStart();

        }
    }



}

using HeroesDB;
using HeroModels;
using Microsoft.EntityFrameworkCore;
using SolutionItems;

namespace Heroes
{
    public partial class SelectCharacter
    {
        private static readonly HeroCreation heroCreation = new();
        private static readonly Mage mage = heroCreation.mage;
        private static readonly Archer archer = heroCreation.archer;
        public static IHero CurrentCharacter;

        private string _cnstr;
        private static DbContextOptionsBuilder _optionsBuilder;
        public SelectCharacter()
        {
            _cnstr = Program._configuration["ConnectionStrings:HeroesDB"];
            _optionsBuilder = new DbContextOptionsBuilder<HeroesDBContext>().UseSqlServer(_cnstr);
        }

        private static void RegisterUser()
        {
            using var context = new HeroesDBContext(_optionsBuilder.Options);
            
            var user = new UserRegistration.UserController();
            Console.WriteLine("Please enter a username:");
            var username = Console.ReadLine();
            //Check if username is already taken
            var userExists = context.Users.Any(u => u.Username == username);
            if (userExists)
            {
                Console.WriteLine("Username already exists. Please try again.");
                RegisterUser();
            }
            else
            {
                user.Username = username;
            }
            Console.WriteLine("Please enter a password:");
            var password = Console.ReadLine();
            //ensure password is at least 8 characters
            if (password.Length < 4)
            {
                Console.WriteLine("Password must be at least 4 characters. Please try again.");
                RegisterUser();
            }
            else
            {
                user.Password = password;
            }
            user.Password = password;
            user.Username = username;
            context.Users.Add(user);
            context.SaveChanges();
        }
    }
}

I've tried reformatting the "Using var context" Statement a number of different ways I saw on the Docs. Including changing it to just open and close connections. I've also tried moving around where all of the connection logic is. I'm not sure if the problem is that I am trying to access the DB from the SelectCharacter file, or if theres an issue in the Program.cs file.


Solution

  • You need to decide what's a static method and what's an instance method. You've got

    public SelectCharacter()
    {
        _cnstr = Program._configuration["ConnectionStrings:HeroesDB"];
        _optionsBuilder = new DbContextOptionsBuilder<HeroesDBContext>().UseSqlServer(_cnstr);
    }
    
    private static void RegisterUser()
    {
        using var context = new HeroesDBContext(_optionsBuilder.Options);
        
    

    Since RegisterUser() is a static method, there's no SelectCharacter instance and the SelectCharacter() constructor that assigns _optionsBuilder hasn't run.