2017-11-11 201 views
0

我有2個表格,它們之間的關係使用字段表格Id1表格Id2鏈接。在EF.6中使用數據註釋的OneOrZero關係?

我想要的是,如果兩個數據都鏈接,則字段將填充主鍵值

,在平均場TableId2表1將填補Table2.Id還現場TableId1表2將充滿Table1.Id

而且,我也希望兩個字段都可以是空的。這意味着他們不知道(數據是獨立的)。

public class Table1 
{ 
    [Key] 
    public int Id { get; set; } 
    public string table1_desc { get; set; } 

    public int? TableId2 { get; set; } 
    [ForeignKey("TableId2")] 
    public Table2 Table2 { get; set; } 
} 

public class Table2 
{ 
    [Key] 
    public int Id { get; set; } 
    public string Table2_desc { get; set; } 

    public int? TableId1 { get; set; } 
    [ForeignKey("TableId1")] 
    public Table1 Table1 { get; set; } 
} 

我的問題是,如何解決使用數據註解這個問題?那可能嗎 ?。該代碼上面給我的錯誤:

Unable to determine the principal end of an association between the types 'ConsoleApplication1.Data2' and 'ConsoleApplication1.Data1'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations. 

謝謝你, 祭告Haslim

回答

0

不,那是不可能的 - 在所有。

外鍵約束需要一個主體類型和一個依賴類型,所以你可以配置級聯,如果nessacary。這完全是錯誤信息告訴你的。

如果你需要一個實際的例子,想想一隻母貓和它的一隻小貓。母貓是校長。它可以存在沒有它的小貓。但小貓強烈依賴其主要母親。

刪除母親和刪除將級聯到它的小貓。 刪除孩子,母親將繼續活下去。

所以你必須做出一個實體的主要

public class Table1 
{ 
    [Key] 
    public int Id { get; set; } 
    public string table1_desc { get; set; } 
    public Table2 Table2 { get; set; } 
} 

而另外一個依賴

public class Table2 
{ 
    [Key, ForeignKey("Table1")] 
    public int Id { get; set; } 
    public string Table2_desc { get; set; } 

    public Table1 Table1 { get; set; } 
} 
0

有一種方法可以做到這一點,而不是與數據註解雖然我不認爲我會推薦它(如果你不喜歡它,隨時可以投我一票)。

訣竅是將兩個關係映射爲一對多關係。例如與賽車和車手:

public class Car 
{ 
    public int CarId { get; set; } 
    public string Name { get; set; } 
    public int? DriverId { get; set; } 
    public Driver Driver { get; set; } 
} 

public class Driver 
{ 
    public int DriverId { get; set; } 
    public string Name { get; set; } 
    public int? CarId { get; set; } 
    public Car Car { get; set; } 
} 

映射:

modelBuilder.Entity<Driver>() 
      .HasOptional(d => d.Car).WithMany() 
      .HasForeignKey(d => d.CarId); 
modelBuilder.Entity<Car>() 
      .HasOptional(c => c.Driver).WithMany() 
      .HasForeignKey(c =>c.DriverId); 

但這裏的缺點。你必須建立雙方的關係,否則你可以得到一個CarDriverId而所屬的驅動程序有CarId = null。但是,如果你這樣做......

var car = new Car { Name = "Ford" }; 
var driver = new Driver { Name = "Henry" }; 
driver.Car = car; 
car.Driver = driver; 

db.Set<Car>().Add(car); 
db.SaveChanges(); 

...拋出一個異常:

無法確定相關的操作有效的排序。由於外鍵約束,模型要求或商店生成的值,可能會存在依存關係。

是的,司機需要新車的主鑰匙,而汽車是新車的主人。

所以這需要你自己做這種方式:

var car = new Car { Name = "Ford" }; 
var driver = new Driver { Name = "Henry" }; 
driver.Car = car; 

db.Set<Car>().Add(car); 

using(var ts = new TransactionScope()) 
{ 
    db.SaveChanges(); 
    car.Driver = driver; 
    db.SaveChanges(); 
    ts.Complete(); 
} 

不是太優雅,是嗎?

供參考:這是this answer其中一個選項的詳細說明,其中您可能會找到更好的選擇。