在我的EF6 Code First模型中,我有以下类:
class User : IdentityUser // so it has public string Id!
{
public virtual long ItemId { get; set; }
public virtual Item Item { get; set; }
}
class Item
{
public virtual long Id { get; set;
public virtual string UserId { get; set; }
public virtual User User { get; set; }
}
在我的上下文中,我执行以下操作:
OnModelCreating(DbModelBuilder mB)
{
mB.Entity<User>().HasOptional(x => x.Item).WithOptionalPrincipal(x => x.User).WillCascadeOnDelete(false);
}
但是,我的移植产生了以下内容:
CreateTable(
"dbo.Items",
c => new
{
Id = c.Long(nullable: false, identity: true),
UserId = c.String(),
User_Id = c.String(maxLength: 128),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.Users", t => t.User_Id)
.Index(t => t.User_Id);
我忘了做什么?
更新:我还尝试将[ForeignKey("User")]
添加到Item.UserId
UPDATE2: 我发现了一种解决方法,但它不是很漂亮......
OnModelCreating(DbModelBuilder mB)
{
mB.Entity<User>().HasOptional(x => x.Item).WithMany().HasForeignKey(x => x.ItemId);
mB.Entity<Item>().HasOptional(x => x.User).WithMany().HasForeignKey(x => x.UserId);
}
答案 0 :(得分:0)
据我了解,Entity Framework通过使2个实体共享相同的主键来实施一对一的关系。这意味着不需要单独的外键列,因为主键属性也充当外键。
因此,删除多余的外键并将Item的键的类型更改为string,以便它可以引用用户的ID:
class User : IdentityUser // so it has public string Id!
{
public virtual Item Item { get; set; }
}
class Item
{
public string Id { get; set;}
public virtual User User { get; set; }
}
现在,当关系的两端都是必需的或双方都是可选的时,实体框架无法识别依赖关系和主体。依赖项是获取引用主体密钥的外键的依赖项。
所以试试这个:
modelBuilder.Entity<User>()
.HasOptional(f => f.Item). //Item is dependent and
//gets the foreign key
.WithOptionalPrincipal(s => s.User);
<强>限制性条款强>
我没有试过这个或做过这个,我没有得到的是这个。
如果两端都是可选的,那么Item
如何拥有一个也是主键的User
的外键?主键是必需的,但可选的外键不是。所以他们不可能是同一个。
因此,如果EF现在添加了一个可选的外键,我会为它添加一个唯一的索引以确保它是1到1.因为它可以为空,所以你需要在迁移中使用sql来实现它
Sql("CREATE INDEX ON Item(User_Id) UNIQUE WHERE User_Id IS NOT NULL")
参考文献:
http://msdn.microsoft.com/en-us/data/jj713564
http://msdn.microsoft.com/en-us/data/jj591620.aspx
它在该页面上说:
当关系的两端都是可选的时,请使用 HasOptional之后的WithOptionalPrincipal或WithOptionalDependent 方法
Do I define a relationship between two entities on the dependent or the principal?