WithRequired() No Extension Method Defined

asp.net-identity asp.net-mvc c# entity-framework-core

Question

I have been searching for the past three hours trying to figure out what is going on and finally had to break down and post a question.

I am trying to add WithRequired()/HasRequired() to my model builder for ApplicationUser, but it tells me that it is not defined.

Am I just being completely ignorant here, or has this changed with the .Net Core/EF Core frameworks?

ApplicationUser:

public class ApplicationUser : IdentityUser
{
    [Required]
    [StringLength(100)]
    public string Name { get; set; }

    public ICollection<Following> Followers { get; set; }

    public ICollection<Following> Followees { get; set; }

    public ApplicationUser()
    {
        Followers = new Collection<Following>();
        Followees = new Collection<Following>();
    }
}

Following.cs:

public class Following
{
    [Key]
    [Column(Order = 1)]
    public string FollowerId { get; set; }

    [Key]
    [Column(Order = 2)]
    public string FolloweeId { get; set; }

    public ApplicationUser Follower { get; set; }
    public ApplicationUser Followee { get; set; }
}

ApplicationDbContext:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public DbSet<Gig> Gigs { get; set; }
    public DbSet<Genre> Genres { get; set; }

    public DbSet<Attendance> Attendances { get; set; }

    public DbSet<Following> Followings { get; set; }

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        // Customize the ASP.NET Identity model and override the defaults if needed.
        // For example, you can rename the ASP.NET Identity table names and more.
        // Add your customizations after calling base.OnModelCreating(builder);

        builder.Entity<Attendance>()
            .HasKey(c => new { c.GigId, c.AttendeeId });

        builder.Entity<ApplicationUser>()
            .HasMany(u => u.Followers);

        builder.Entity<ApplicationUser>()
            .HasMany(u => u.Followees);
    }
}

Error when I try to add WithRequired()/HasRequired(): none

1
8
7/14/2016 7:15:36 PM

Accepted Answer

@Tseng is close, but not enough. With the proposed configuration you'll get exception with message:

The child/dependent side could not be determined for the one-to-one relationship that was detected between 'Account.User' and 'User.Account'. To identify the child/dependent side of the relationship, configure the foreign key property. See http://go.microsoft.com/fwlink/?LinkId=724062 for more details.

It's basically explained in the documentation from the link.

First, you need to use HasOne and WithOne.

Second, you must use HasForeignKey to specify which one of the two entities is the dependent (it cannot be detected automatically when there is no separate FK property defined in one of the entities).

Third, there is no more required dependent. The IsRequired method can be used to specify if the FK is required or not when the dependent entity uses separate FK (rather than PK as in your case, i.e. with the so called Shared Primary Key Association because PK apparently cannot be null).

With that being said, the correct F Core fluent configuration of the posted model is as follows:

modelBuilder.Entity<User>()
    .HasOne(e => e.Account)
    .WithOne(e => e.User)
    .HasForeignKey<Account>(e => e.AccountId);

and the result is:

migrationBuilder.CreateTable(
    name: "User",
    columns: table => new
    {
        UserId = table.Column<int>(nullable: false)
            .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
        Email = table.Column<string>(nullable: true),
        Name = table.Column<string>(nullable: true)
    },
    constraints: table =>
    {
        table.PrimaryKey("PK_User", x => x.UserId);
    });

migrationBuilder.CreateTable(
    name: "Account",
    columns: table => new
    {
        AccountId = table.Column<int>(nullable: false),
        CreatedDateTime = table.Column<DateTime>(nullable: false)
    },
    constraints: table =>
    {
        table.PrimaryKey("PK_Account", x => x.AccountId);
        table.ForeignKey(
            name: "FK_Account_User_AccountId",
            column: x => x.AccountId,
            principalTable: "User",
            principalColumn: "UserId",
            onDelete: ReferentialAction.Cascade);
    });
7
4/21/2017 5:07:05 PM

Popular Answer

Pretty much the same, with other names.

modelBuilder.Entity<User>()
    .HasOne(s => s.Account) 
    .WithOne(ad => ad.User)
    .IsRequired(false);


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow