2013-10-20 54 views
2

如何在ASP.NET MVC中使用實體框架表示一對多關係?如何表示與實體框架的一對多關係?

我的項目是一個會議呼叫項目。我有一個數據庫Conferences。每個虛擬的Conference房間有一個Title,一個OwnerName,和一個不同的DialInNumbers列表。我知道,爲了使這種關係爲ConferenceDialInNumbers,我至少需要兩個表:一個用於Conferences,至少一個用於DialInNumbers。我一直在創建,修改和訪問DialInNumbers時遇到問題。我的代碼肯定缺少一些東西。讓我們一起來看看:

下面是Conference型號:

public class Conference 
{ 
    public int Id { get; set; } 
    public string Title { get; set; } 
    public string OwnerName { get; set; } 
    public List<string> DialInNumbers { get; set; } 
} 

該模型需要DbContext(不知道爲什麼...)

public class ConferenceDbContext : DbContext 
{ 
    public DbSet<Conference> Conferences { get; set; } 
} 

然後,在ControllerConferenceController),我們可以CreateEdit a Conference。例如:

public ActionResult Create(Conference conference) 
{ 
    if (ModelState.IsValid) 
    { 
     conference.DialInNumbers = ThreeRandomlyGeneratedPhoneNumbers(); 

     db.Conferences.Add(conference); 
     db.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 

    return View(conference); 
} 

當我保存數據庫更改時,我只得到一個表爲Conferences。如何獲得多個表格,以及如何將它們鏈接到實體框架中?

謝謝。

+0

你在做代碼優先嗎? http://msdn.microsoft.com/en-us/data/jj591620.aspx –

+0

請參閱http://stackoverflow.com/questions/8317749/entity-framework-code-first-liststring-property-mapping – haim770

回答

4

您無法定義實體和字符串之間的1:N關係。在EF中,只能在兩個實體之間建立關係,因此DialInNumber應該由實體表示。

public class DialInNumber { 
    public int ID { get; set; } 
    public string Number { get; set; } 
    public virtual Conference Conference { get; set;} 
} 

Conference類應引用這些實體的集合而不是字符串的集合。

public class Conference { 
    public string Title { get; set; } 
    public string OwnerName { get; set; } 
    public virtual ICollection<DialInNumber> DialInNumbers { get; set; }  
} 

並記:爲了使延遲加載工作中,DialInNumbers屬性應該是虛擬

+0

輝煌!這工作。非常感謝。問題:爲什麼延遲加載需要'Conference'和'DialInNumbers'中的'virtual'屬性? – theLearningChan

+0

這是設計所需要的。這是框架如何用EF修改內容的方式。 –

+1

EF使用代理類的概念 - 當您從數據庫請求實體時,它不會創建您的類的實例,但會創建代理類來處理更改跟蹤,延遲加載等。代理類需要重寫導航屬性,這就是爲什麼他們必須是虛擬的。 –

0
public class Conference 
{ 
    public int Id { get; set; } 
    public string Title { get; set; } 
    public string OwnerName { get; set; } 
    public List<string> DialInNumbers { get; set; } 
} 

你的實體只有標量屬性。這意味着它不涉及另一個實體。在你的具體情況中,屬性DialInNumbers是一個不是實體列表的字符串列表。實體框架將導航屬性轉換爲表格關係,但現在情況並非如此。

如果您確實想擁有一個DialInNumbers表,您需要有一個DialNumber的列表。

public class Conference 
{ 
    public int Id { get; set; } 
    public string Title { get; set; } 
    public string OwnerName { get; set; } 
    public List<DialNumber> DialInNumbers { get; set; } 
} 

public Class DialNumber 
{ 
    public string Number{get;set;} 
    public int ConferenceId{get;set;} 
    public Conference Conference{get;set;} 
} 

您需要在您的配置類中爲導航屬性配置您的實體。

modelBuilder 
    .Entity<DialNumber>() 
    .HasRequired(p => p.Conference); 

如果你想使用實體的ID,您將需要修改你DialNumber到:

public Class DialNumber 
{ 
    public string Number{get;set;} 
    public Conference Conference{get;set;} 
} 

modelBuilder 
    .Entity<DialNumber>() 
    .HasRequired(p => p.Conference); 
    .WithMany(b => b.DialNumber) 
    .HasForeignKey(p => p.ConferenceId); 

這將讓您有以後安裝實體的開銷更少,將讓你讓你的外鍵以你想要的方式命名,在這種情況下,使用ConferenceId而不是默認的語法(如第一種情況下)「Conference_Id」。