Why does EF generate a foreign key?

I need to do one to one (optional).

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<PinnacleAccount>().HasKey(x => x.Id);

    modelBuilder.Entity<PinnacleAccount>()
        .HasRequired(x => x.User)
        .WithOptional(x => x.PinnacleAccount);

    base.OnModelCreating(modelBuilder);
}

and when I run the "Add-Migration Init", I check the generated migration and see:

CreateTable(
                "dbo.PinnacleAccounts",
                c => new
                    {
                        Id = c.Int(nullable: false, identity: true),
                        ClientId = c.String(),
                        Password = c.String(),
                        PercentForBet = c.Int(nullable: false),
                        UserId = c.String(),
                        User_Id = c.String(nullable: false, maxLength: 128),
                    })
                .PrimaryKey(t => t.Id)
                .ForeignKey("dbo.AspNetUsers", t => t.User_Id)
                .Index(t => t.User_Id);

But I have a UserId property. Why ef creates User_Id

   public class ApplicationUser : IdentityUser
    {
        public virtual PinnacleAccount PinnacleAccount { get; set; }
        public int? PinnacleAccountId { get; set; }

        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here
            return userIdentity;
        }
    }
+4
source share
4 answers

When creating a 1: 0.1 relationship in an entity structure, the primary key of the first object must be the same as the primary key of the second object. You cannot specify which property is FK because this is optional. I will explain:

a User PinnacleAccount, 1: 0.1. , PinnacleAccount User. , PinnacleAccount , User.

PinnacleAccount , UserId. , PinnacleAccount :

public class PinnacleAccount
{
    public string UserId { get; set; } //PK AND FK
    public string ClientId  { get; set; }
    public string Password { get; set; }
    public string PercentForBet { get; set; }
}

Mapping:

modelBuilder.Entity<PinnacleAccount>().HasKey(x => x.UserId);
modelBuilder.Entity<User>()
    .HasOptional(i => i.PinnacleAccount)
    .WithRequired(x => x.User);

1: 0.1.

, !

+4

,

this.HasOptional(t => t.User)
                .WithMany(t => t.PinnacleAccount)
                .HasForeignKey(d => d.UserId);
+2

, EF , Fluent API, . , , - , .

FK, . "" UserId FK. , PinnacleAccount UserId - , User_Id, AspNetUsers, UserId 128.

, UserId 128, [MaxLenght] .hasMaxLength() API, foreing.

+1

@Fabio Luz , , , , .

My 'PinnacleAccount' ( GUID, ):

public class PinnacleAccount
{
  [Required]
  [Key]
  [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  public Guid Id { get; set; }

  public virtual ApplicationUser User { get; set;  }
  [Required]
  public virtual string UserId { get; set; }  
}

PinnacleAccount, , . .

-, UserId UserIdOld , :

public override void Up()
{
    DropForeignKey("dbo.PinnacleAccount", "UserId", "dbo.AspNetUsers");
    DropIndex("dbo.PinnacleAccount", new[] { "UserId" });
    RenameColumn(table: "dbo.PinnacleAccount", name: "UserId", newName: "User_Id");
    AddColumn("dbo.PinnacleAccount", "UserIdOld", c => c.String(nullable: false));
    AlterColumn("dbo.PinnacleAccount", "User_Id", c => c.String(maxLength: 128));
    CreateIndex("dbo.PinnacleAccount", "User_Id");
    AddForeignKey("dbo.PinnacleAccount", "User_Id", "dbo.AspNetUsers", "Id");
}

public override void Down()
{
    DropForeignKey("dbo.PinnacleAccount", "User_Id", "dbo.AspNetUsers");
    DropIndex("dbo.PinnacleAccount", new[] { "User_Id" });
    AlterColumn("dbo.PinnacleAccount", "User_Id", c => c.String(nullable: false, maxLength: 128));
    DropColumn("dbo.PinnacleAccount", "UserIdOld");
    RenameColumn(table: "dbo.PinnacleAccount", name: "User_Id", newName: "UserId");
    CreateIndex("dbo.PinnacleAccount", "UserId");
    AddForeignKey("dbo.PinnacleAccount", "UserId", "dbo.AspNetUsers", "Id", cascadeDelete: true);
}

UserId User_Id UserId ( alter).

:

 public class PinnacleAccount
{
    public string UserId { get; set; }

  public virtual ApplicationUser User { get; set;  }
}

Mapping, @Fabio Luz.

, :

public override void Up()
{
    DropIndex("dbo.PinnacleAccount", new[] { "User_Id" });
    RenameColumn(table: "dbo.PinnacleAccount", name: "User_Id", newName: "UserId");
    DropPrimaryKey("dbo.PinnacleAccount");
    AlterColumn("dbo.PinnacleAccount", "UserId", c => c.String(nullable: false, maxLength: 128));
    AddPrimaryKey("dbo.PinnacleAccount", "UserId");
    CreateIndex("dbo.PinnacleAccount", "UserId");
    DropColumn("dbo.PinnacleAccount", "Id");
    DropColumn("dbo.PinnacleAccount", "UserIdOld");
}

public override void Down()
{
    AddColumn("dbo.PinnacleAccount", "UserIdOld", c => c.String(nullable: false));
    AddColumn("dbo.PinnacleAccount", "Id", c => c.Guid(nullable: false, identity: true));
    DropIndex("dbo.PinnacleAccount", new[] { "UserId" });
    DropPrimaryKey("dbo.PinnacleAccount");
    AlterColumn("dbo.PinnacleAccount", "UserId", c => c.String(maxLength: 128));
    AddPrimaryKey("dbo.PinnacleAccount", "Id");
    RenameColumn(table: "dbo.PinnacleAccount", name: "UserId", newName: "User_Id");
    CreateIndex("dbo.PinnacleAccount", "User_Id");
}

1: 0.1. , , !

0

Source: https://habr.com/ru/post/1620994/


All Articles