我需要一对一(可选)。
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);
}
当我运行&#39; Add-Migration Init&#39;我检查生成的迁移并查看:
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);
但我有属性UserId。为什么ef创建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;
}
}
答案 0 :(得分:4)
当您在实体框架中建立1:0.1的关系时,第一个实体的主键必须与第二个实体的主键相同。您无法指定哪个属性是FK,因为它不是必需的。我会解释一下:
如果User
只有一个PinnacleAccount
,则为1:0.1关系。因此,每个PinnacleAccount
都属于User
。这意味着,PinnacleAccount
是一个弱实体,因此,它的主键也是一个User
外键。
PinnacleAccount
不应该有自己的ID,只有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; }
}
映射:
modelBuilder.Entity<PinnacleAccount>().HasKey(x => x.UserId);
modelBuilder.Entity<User>()
.HasOptional(i => i.PinnacleAccount)
.WithRequired(x => x.User);
这是建立1:0.1关系的唯一方法。
希望它有所帮助!
答案 1 :(得分:2)
也许您需要在模型中声明映射关系
this.HasOptional(t => t.User)
.WithMany(t => t.PinnacleAccount)
.HasForeignKey(d => d.UserId);
答案 2 :(得分:0)
@Fabio Luz给出了正确的答案,但对于已经设置错误且需要纠正错误的任何人,请按照以下方式进行操作。
我的&#39; PinnacleAccount&#39;看起来如下(我使用GUID,但你明白了):
.parent
我可以从PinnacleAccount访问用户,但不是相反,我想纠正。为此,我必须创建两个迁移。
首先,我将UserId属性编辑为UserIdOld并创建了类似的迁移:
$('.mobile-select-supplier a').click(function() {
$(this).closest('.parent').find('.extra-suppliers.mobile.only').show();
});
这允许我释放UserId列名,并使用UserId填充User_Id列(因为这是alter语句)。
然后我将课程改为:
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; }
}
随后对@Fabio Luz描述的映射进行了更改。
然后我创建了第二个迁移,看起来像:
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);
}
这给了我正确的1:0.1。感谢Fabio展示如何正确创建一个!