2011-03-24 160 views
7

我試圖創建實體框架(代碼前)的許多一對多的關係,根據下面的帖子:Database design for limited number of choices in MVC and Entity Framework?實體框架中與聯結表的多對多關係?

但是,我不能讓它正常工作,我我確定我做錯了一些很簡單的事情。下面是圖我沒有從我的嘗試:

enter image description here

聯接表的一點是,我需要有額外的屬性,等級,在關係,這樣我就可以用一個走不顧問和計劃之間的直接關係。我在設計器中手動添加了ConsultantProgramLink實體,然後分別添加關聯到程序和顧問,選擇爲每個添加FK,然後將它們都作爲主鍵。但是當我這樣做的時候,它並沒有像我期望的那樣工作:

如果我在顧問和程序之間做了一個直接關聯,那麼我就可以在我的代碼中引用Consultant.Programs。但是現在對於聯結表來說這不起作用。有什麼辦法可以解決這個問題嗎?還是我總是需要通過交叉點屬性(Consultant.ConsultantProgramLink.Programs)?無論如何,即使我嘗試通過交叉路口屬性,它也無濟於事。我可以在我的代碼中執行Consultant.ConsultantProgramLink,但另一個點不會給我導航屬性程序(由於某種原因,它也僅僅是程序,爲什麼?如果我最終可以訪問它們,我可以重命名它們嗎?) 。

那麼我做錯了什麼?爲什麼我無法通過代碼中的點符號訪問屬性?

回答

11

將交接表建模爲實體後,確實會在ConsultantProgram之間丟失直接的多對多關係。這就是它的工作原理。您將在交接表中具有直接的多對多關係或附加屬性。不是都。如果你想同時你可以嘗試在Consultant和使用LINQ查詢創建自定義Programs屬性來獲取相關的程序:

public IEnumerable<Program> Programs 
{ 
    get 
    { 
     return this.ConsultantProgramLinks.Select(l => l.Program); 
    } 
} 

的例子也是你的最後一個問題的解釋。您不能在ConsultantProgramLink上擁有Program財產,因爲它是相關實體的集合,而不是單個實體(應稱爲ConsultantProgramLinks)。 ConsultantProgramLink實體中的財產簡單地稱爲Program,因爲它代表單個實體不收集。

編輯:

如果您需要在每個Program與每個Consultant自動關聯,必須強制執行它,當您要創建新的Program。暴露爲單獨的實體有結表將可能讓你輕鬆地實現它:

var program = new Program(); 
... 
context.Programs.AddObject(program); 

var ids = from c in context.Consultants 
      select c.Id; 

foreach (var id in ids) 
{ 
    var link = new ConsultantProgramLink 
     { 
      ConsultantId = id, 
      Program = program 
     }; 
    context.ConsultantProgramLinks.AddObject(link); 
} 

context.SaveChanges(); 

如果要添加新Consultant你必須創建指向同樣的方式的所有程序。

缺點是,如果您有例如1000位顧問,此構造將創建1001個數據庫插入,其中每個插入將在單獨的數據庫往返中執行。爲了避免它,唯一的選擇是在程序表上使用存儲的程序或觸發器。

+0

好的,謝謝,這是有道理的。但我想知道我是否在想這一切都是錯誤的?我不知道如何實際做我想要的: – Anders 2011-03-24 12:05:16

+0

說我創建一個新的顧問。我希望該顧問在其程序屬性中包含所有程序。然後,我希望用戶能夠爲每個人設定熟練程度。但1:如何將程序表中的所有程序分配給每位顧問? 2:如果我將新程序添加到程序表(我希望能夠做到)怎麼辦?你看到我需要什麼嗎?程序列表,如Adobe Illustrator,MS Word等,這個列表應該是可擴展的。但是,每位顧問應該始終「擁有」其程序屬性中的所有程序,並且只能在編輯配置文件時設置關卡... – Anders 2011-03-24 12:06:10

+0

我會考慮它的。 – 2011-03-24 12:47:37