1

I'm trying to get TPH model database inheritance from ApplicationUser:

public class Customer:ApplicationUser
    {
        public DateTime? AddeDateTime { get; set; }

        public int? DietLenght { get; set; }
        public int? ConsultationCount { get; set; }
        public int? PlannedWeight { get; set; }
        public int? Age { get; set; }
        public int? Height { get; set; }

How to access those properties ? I tried:

var customerUser = await _context.Users.FirstOrDefaultAsync(x => x.Id == user.Id);

but i got ApplicationUser. And ApplicationUser doesn't have the properties to set up, so i can't make it like that.

customerUser .ConsultationCount = model.ConsultationCount;
customerUser .DietLenght = model.DietLenght;
customerUser .Height = model.Height;
customerUser .Age = model.Age;

I also tried:

var dataUser = user as Customer;

but it didn't work either.

Need it to create new User in my app

if (ModelState.IsValid)
            {
                var currentlyLogInUser = _userManager.GetUserAsync(HttpContext.User).Result;
                var currentlyLogInUserId = currentlyLogInUser.Id;
                var user = new ApplicationUser
                {
                    UserName = model.Email,
                    Email = model.Email,
                    Name = model.Name,
                    Surname = model.Surname
                };
                var result = await _userManager.CreateAsync(user, model.Password);
                if (result.Succeeded)
                {
                    var resultRole = await _userManager.AddToRoleAsync(user, "Customers");
                    if (resultRole.Succeeded)
                    {
                        _logger.LogInformation("User created a new account with password.");


                            var customer = (Customer) user;
                            customer.DieticianId = currentlyLogInUserId;
                            customer.AddeDateTime = DateTime.Today;
                            customer.ConsultationCount = model.ConsultationCount;
                            customer.DietLenght = model.DietLenght;
                            customer.Height = model.Height;
                            customer.Age = model.Age;
                            _context.Users.Update(customer);
                            await _context.SaveChangesAsync();


                    }

                    return RedirectToLocal(returnUrl);
                }
                AddErrors(result);
            }

            // If we got this far, something failed, redisplay form
            return View();
        }
Systu
  • 17
  • 7
  • https://stackoverflow.com/questions/21062981/farther-extending-applicationuser-class-in-asp-net-mvc5-identity-system – ColinM Nov 13 '17 at 12:52

1 Answers1

0

The Users property of the context is a DbSet<ApplicationUser>, so it will only ever return ApplicationUser instances. You need a DbSet<Customer> to get back a Customer.

Alternatively, you can simply cast to the right type after the fact. The entity returned is still a Customer; it was simply upcast to ApplicationUser by the DbSet type-constraint. As a result you can do:

if (user is Customer)
{
    var customer = (Customer)user;
    // work with `customer`
}

With C# 7's pattern matching you can simplify that to:

if (user is Customer customer)
{
    // work with `customer`
}

Or if you have have multiple different user types, you can employ a switch statement with pattern matching:

switch (user)
{
    case Customer customer:
        // work with `customer`
        break;
    case AnotherUserType another:
        // work with `another`
        break;
    // etc.
}
Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • Not sure what you're saying. – Chris Pratt Nov 13 '17 at 14:10
  • i can't cast User to Customer i got InvalidCastException When i tried to work with Dbset i got empty context (There were no users there) – Systu Nov 13 '17 at 14:58
  • Most likely, you're creating your `Customer` users incorrectly as well. In particular, if you use the `UserManager` controller property that's scaffolded by Identity, that is actually an instance of `UserManager`. If you attempt to save a `Customer` with that, it will upcast to `ApplicationUser` first *and then save*. In other words, you're only ever saving `ApplicationUser` instances. You need to create the user via your `DbSet` or create an instance of `UserManager` and use that. – Chris Pratt Nov 13 '17 at 15:00
  • before i tried do it by DbSet but it dont has User properties (Id,name,Surname,Emial) When i'm Create model to my application i'm use https://weblogs.asp.net/manavi/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-1-table-per-hierarchy-tph there i have read I only define one DbSet for the base class which is BillingDetail. Code First will find the other classes in the hierarchy based on Reachability Convention. So i dont have DbSet – Systu Nov 13 '17 at 15:17
  • next im try made "private readonly UserManager _userManager;" But got InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager`1[Project.Models.Customer]' while attempting to activate 'Project.Controllers.CustomersController'. – Systu Nov 13 '17 at 15:24