Mediator Mediator - 4 months ago 31
C# Question

Why EF generate foreign key?

I need make 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 'Add-Migration Init' I check 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 property UserId. Why ef create 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;
}
}

Answer

When you make a 1:0.1 relationship in entity framework, the primary key of the first entity must be same as the primary key of the second entity. You can't specify which property is the FK because it is not necessary. I will explain:

If a User has only one PinnacleAccount, it is a 1:0.1 relationship. So, every PinnacleAccount belongs to an User. It means that, PinnacleAccount is a weak entity, so, its primary key is also an User foreign key.

PinnacleAccount should not have its own Id, just the UserId. So, PinnacleAccount should be like this:

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);

This is the only way to make 1:0.1 relationship.

Hope it helps!