Search code examples
c#asp.net-mvcasp.net-core.net-6.0

How to create a custom object from a register page


I want to create a Department object that doesn't exist yet an assign it a AppUser along side a Person object then add it to database during the registration process with .net 6.0 ef identity framework

I tried

var user = CreateUser();

await _userStore.SetUserNameAsync(user, Input.Email, CancellationToken.None);
await _emailStore.SetEmailAsync(user, Input.Email, CancellationToken.None);
if (!String.IsNullOrEmpty(Input.Department))
{
    if (_context.Departments.Where(o => o.DepartmentName == Input.Department) == null)
    {
        await _context.Departments.AddAsync(new Department()
        {
            DepartmentId = Guid.NewGuid().ToString(),
            DepartmentName = Input.Department
        });
        await _context.Persons.AddAsync(new Person()
        {
            PersonId = Guid.NewGuid().ToString(),
            Name = Input.Name,
            Department = await _context.Departments.Where(o => o.DepartmentName == Input.Department).FirstOrDefaultAsync()
        });
        user.Department = await _context.Departments.Where(o => o.DepartmentName == Input.Department).FirstOrDefaultAsync();
    }
    else
    {
        await _context.Persons.AddAsync(new Person()
        {
            PersonId = Guid.NewGuid().ToString(),
            Name = Input.Name,
            Department = _context.Departments.Where(o => o.DepartmentName == Input.Department).FirstOrDefault()
        });      
        user.Department = await _context.Departments.Where(o => o.DepartmentName == Input.Department).FirstOrDefaultAsync();
    }
}

and it keeps throwing nulls

Department.cs

public class Department
{
    [Key]
    public string DepartmentId { get; set; }
    public string DepartmentName { get; set; }
    public List<AppUser> Users { get; set; }
}

AppUser.cs

public class AppUser : IdentityUser
{
    [DefaultValue(null)]
    public string Name { get; set; }
    public Department Department { get; set; }
}

Person.cs

public class Person
{
    [Key]
    public string PersonId { get; set; }
    public string Name { get; set; }
    [DefaultValue(0)]
    public int Set1 { get; set; }
    [DefaultValue(0)]
    public int Set2 { get; set; }
    [DefaultValue(0)]
    public int Set3 { get; set; }
    public string DepartmentId { get; set; }
    public Department Department { get; set; }
}

Solution

  • I want to create a Department object that doesn't exist yet an assign it a AppUser along side a Person object then add it to database during the registration process with .net 6.0 ef identity framework.

    It keeps throwing nulls

    Yes, that's expected to be null always. I found two major flows within your shared code.

    First of all, in the following code,

    if (_context.Departments.Where(o => o.DepartmentName == Input.Department) == null)
    

    The condition will not work as intended because Where returns an IQueryable, and comparing it to null will always be false.

    Another mistake is, you're trying to use the newly added department immediately after adding it to the DbContext. However, the changes are not saved yet, so the department won't be available in the subsequent queries until SaveChangesAsync is called.

    Instead of doing so, you could refactor your code as following:

    var department = await _context.Departments
        .FirstOrDefaultAsync(o => o.DepartmentName == Input.Department);
    
    if (department == null)
    {
        department = new Department
        {
            DepartmentId = Guid.NewGuid().ToString(),
            DepartmentName = Input.Department,
            Users = new List<AppUser>()
        };
    
        await _context.Departments.AddAsync(department);
        await _context.SaveChangesAsync(); 
    }
    

    Note: Within my updated code, first I am checking the department table from the input using FirstOrDefaultAsync to retrieve the department by name. If it doesn't exist, department will be null. After that, If the department doesn't exist, create it, add it to the context, and save changes to the database to ensure it is available for subsequent queries. Now you can continue your rest of the code snippet which can now check the department which just added earlier.