2016-01-12 60 views
0

我有兩種模型具有雙向0對1關係。EF:我如何從獨立協會轉換爲外鍵協會而不更改架構或丟失數據

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列,然後用不同的名稱重新添加它們。這將打破我現有的所有數據。

我試圖重寫流利的映射使用HasMany()。HasForeignKey(),但也沒有工作。 (儘管它並不是很多,似乎需要獲得HasForeignKey方法?)

什麼是正確的方式來升級這種關係,同時保持架構相同以保留數據庫中的現有數據?

回答

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。關係「A可能有B; B可能有A」是不可能的。

A可能有B,但只有一個B,所以B的主鍵也應該是A的外鍵。

沒關係。這就是1-0.1關係的工作原理。但另一方面,你想要做同樣的事情。

B可能有一個A,但只有一個A,所以A的主鍵也應該是B的外鍵。

這並不好,你試圖做一個「真正的1-1關係」,這是不可能的,因爲你不能同時插入2行。

你想要的是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); 

生成下面的遷移(該屬性的名稱可能會倒在這種情況下,只需更改投標,以幫助和援助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); 

希望它有幫助!