简体   繁体   中英

Entity Framework Core Owned Type Value Object throws required Primary Key to be defined error when used with IdentityUser. Why?

I'm using EF Core 2.2. I have two context in my application. One is AppIdentityDbContext for identity related works and other is AppContext for app related works.

I have an identity user class - ApplicationUser - which has a relation to Profile entity from AppContext and the Profile entity in turn owns a value object ProfileContact .

Here is the code:

ApplicationUser

public class ApplicationUser : IdentityUser<Guid>
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Designation { get; set; }

    public Guid ProfileId { get; set; }
    public Profile Profile { get; set; }
}

Profile

public class Profile : BaseEntity<Guid>, IAggregateRoot
{
    private Profile()
    {
        // required by EF
    }

    public Profile(string brandName, ProfileContact profileContact)
    {
        BrandName = brandName;
        ProfileContact = profileContact;
    }

    public string BrandName { get; set; }

    public ProfileContact ProfileContact { get; private set; }
}

ProfileContact

public class ProfileContact // ValueObject
{
    private ProfileContact()
    {
        // required by EF
    }

    public ProfileContact(string email, string phone, string mobile)
    {
        Email = email;
        Phone = phone;
        Mobile = mobile;
    }

    public string Email { get; private set; }
    public string Phone { get; private set; }
    public string Mobile { get; private set; }
}

IAggregateRoot

IAggregateRoot is an empty interface used to restrict entities from using generic repositories in my project.

public interface IAggregateRoot
{
}

AppContext

Here is the 'Profile' Entity configuration in AppContext .

protected override void OnModelCreating(ModelBuilder builder)
{
    builder.Entity<Profile>(ConfigureProfile);
}

private void ConfigureProfile(EntityTypeBuilder<Profile> builder)
{
    builder.Property(p => p.BrandName)
        .IsRequired()
        .HasMaxLength(50);

    builder.OwnsOne(p => p.ProfileContact);
}

I have configured ProfileContact as owned by Profile entity.

Now whenever user logs in, I get this error:

> 错误说明

> 错误堆栈

Here is my login Post method. I'm using Asp.Net Core Identity scaffolded template.

Login - OnPostAsync

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
   returnUrl = returnUrl ?? Url.Content("~/");

   if (ModelState.IsValid)
   {
       // This doesn't count login failures towards account lockout
       // To enable password failures to trigger account lockout, set lockoutOnFailure: true
       var result = await _signInManager.PasswordSignInAsync(Input.MobileNumber, Input.Password, Input.RememberMe, lockoutOnFailure: true);
       if (result.Succeeded)
       {
         ....

    // If we got this far, something failed, redisplay form
    return Page();
}

Does the value object/owned type needs an key to be defined? What I read and understood about OwnedTypes is that they belong to the same table but can be used as object. Am I doing anything wrong? or I need to add Id property to ProfileContact . If so why? Please assist.

I think this issue is happening if you have two separate context. One for Application and another one for Asp.Net Identity with customized ASP.NET Identity models. And that too with relations between entities in both context.

In that case, adding base.OnModelCreating(builder) in both the context 's OnModelCreating(ModelBuilder builder) solves the issue.

Thanks Gert Arnold for guidance and teaching. Credits to you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM