我有两个具有双向0对1关系的模型。
A,B。A可能有B. B可能有A.
目前在每个类中都设置了导航属性,没有外键属性(使用流畅的语法设置)
public class A{
[key]
public int Id {get;set;}
public B B {get;set;}}
public class B{
[key]
public int Id {get;set;}
A A {get;set;}
}
modelBuilder.Entity<B>()
.HasOptional(b => b.A)
.WithOptionalPrincipal()
.Map(b => b.MapKey("AId"));
modelBuilder.Entity<A>()
.HasOptional(p => p.B)
.WithOptionalPrincipal()
.Map(p => p.MapKey("BId"));
到目前为止,事情正如预期一样正常。
我现在想在我的实体中公开这些ID属性,以帮助更新断开的实体关系。
当我添加属性时,每error 0019: Each property name in a type must be unique on ID field
我会收到“重复名称”错误如果我删除了地图,然后尝试使用这些键,它似乎可以工作,但迁移决定删除FK列,然后使用其他名称重新添加它们。这将破坏我现有的所有数据。
我尝试重写fluent映射以使用HasMany()。HasForeignKey(),但这也不起作用。 (即使它不是很多,似乎需要获得HasForeignKey方法?)
升级此关系的正确方法是什么,同时保持架构相同以保留数据库中的现有数据?
答案 0 :(得分:0)
您当前的映射会生成以下迁移:
CreateTable(
"dbo.B",
c => new
{
Id = c.Int(nullable: false, identity: true),
BId = c.Int(),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.A", t => t.BId)
.Index(t => t.BId);
CreateTable(
"dbo.A",
c => new
{
Id = c.Int(nullable: false, identity: true),
AId = c.Int(),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.B", t => t.AId)
.Index(t => t.AId);
如你所见,这是1-n关系,而不是1-0.1。关系&#34; A可能有B; B可能有一个A&#34;不可能。
A可能有B,但只有一个B,因此B&#39的主键也应该是A的外键。
没关系。这就是1-0.1关系的运作方式。但另一方面,你想做同样的事情。
B可能有一个A,但只有一个A,所以A&#39的主键也应该是B的外键。
那不行,你正试图建立一个真正的1-1关系&#34;,这是不可能的,因为你不能同时插入2行。< / p>
你想要的是1-n关系。因此,请按以下方式修改您的课程:
public class A
{
[Key]
public int Id { get; set; }
public int? BId { get; set; }
public B B { get; set; }
}
public class B
{
[Key]
public int Id { get; set; }
public int? AId { get; set; }
public A A { get; set; }
}
映射:
modelBuilder.Entity<A>()
.HasOptional(i => i.B)
.WithMany()
.HasForeignKey(i => i.BId);
modelBuilder.Entity<B>()
.HasOptional(i => i.A)
.WithMany()
.HasForeignKey(i => i.AId);
它会生成以下迁移(属性&#39;名称可能会被反转。在这种情况下,只需将BId更改为AId,将AId更改为BId):
CreateTable(
"dbo.B",
c => new
{
Id = c.Int(nullable: false, identity: true),
AId = c.Int(),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.A", t => t.AId)
.Index(t => t.AId);
CreateTable(
"dbo.A",
c => new
{
Id = c.Int(nullable: false, identity: true),
BId = c.Int(),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.B", t => t.BId)
.Index(t => t.BId);
希望它有所帮助!