2012-08-08 95 views
1

我是一個Java人,我正在學習.NET領域。我學習的一件事是EF4,我注意到這個有趣的事情。當你聲明與1的實體:N關係到另一個實體,你必須做這樣的事情:爲什麼我需要C#EF中的ID和虛擬集合?

public int CategoryId { get; set; } 
public virtual Category Category { get; set; } 

我的問題是:

是否有一個很好的理由,該框架既需要聲明?

在Java世界中,框架非常聰明,可以確定主鍵是什麼,並將該記錄添加到數據庫中,而無需在實體類上具有單獨的字段。爲什麼.Net在這個小問題上效仿,但令人討厭的問題呢?

+1

你不需要兩個:http://stackoverflow.com/a/5282275/270591+在答案的末尾的鏈接。兩個鏈接更多:http://stackoverflow.com/questions/4703378/ef4-independent-associations-why-avoid-them和http://stackoverflow.com/questions/9253234/what-is-the-point-of-創建外鍵關鍵屬性當使用實體框架 – Slauma 2012-08-08 15:20:20

+0

@Slauma,謝謝你的額外信息。這真的有助於澄清一些 - 我沒有意識到這些是不同類型的關聯。如果您將其作爲答案張貼,我想接受它。 – ametren 2012-08-08 17:07:00

+0

你應該接受@ Yuck的回答。他非常清楚地解釋說,你*可以在沒有FK屬性的情況下工作,舉例和一切,這是你的問題,他回答了。我只對「你不應該」使用FK屬性有一點否決權。但這更像是一場有爭議的辯論。你會發現人們說「你應該」的同樣經常的答案。 – Slauma 2012-08-08 18:35:40

回答

1

你不必這樣做。事實上,你不應該因爲你可以讓你的對象處於不一致的狀態。假設您有:

public class Category { 
    public Int32 Id { get; set; } 
} 

public class SomeClass { 
    public Int32 Id { get; set; } 
    public virtual Category Category { get; set; } 
} 

這是有效的。您只需告知EF在其配置中如何找到外鍵。根據上述內容,它會嘗試使用SomeClass.Category_Id,但您可以隨意更改它。

編輯:如果你想改變外鍵,你可以通過添加配置類和OnModelCreating事件過程中添加它這樣做的:

internal class ForSomeClassEntities : EntityTypeConfiguration<SomeClass> { 
    public ForSomeClassEntities(String schemaName) { 
     this.HasRequired(e => e.Category) 
      .WithMany() 
      .Map(map => map.MapKey("CategoryId")); 
     this.ToTable("SomeClass", schemaName); 
    } 
} 

在你重寫Context類:

protected override void OnModelCreating(DbModelBuilder modelBuilder) { 
    base.OnModelCreating(modelBuilder); 

    modelBuilder.Configurations 
     .Add(new ForSomeClassEntities("SomeSchema")) 
     ; 
} 

使用上面相同的類會告訴EF尋找名爲SomeClass.CategoryId的外鍵屬性。

+0

謝謝,這就是有趣的 - 那麼爲什麼我會按照我在所有教程中描述的方式來看待它? – ametren 2012-08-08 13:57:42

+1

@ametren:因爲它更容易處理。出於這個原因,我不同意Yuck「你不應該」使用FK屬性。 – Slauma 2012-08-08 15:26:01

+0

@Slauma我會同意不同意,只是補充一點,因爲「*更容易*」並不意味着這是一個很好的設計實踐。例如,WebForms **非常容易使用,但頁面模型非常可怕。 – Yuck 2012-08-08 17:39:24

0

當您添加一個虛擬集合/模型到模型,實體框架自動添加一個<ClassName>Id域將其。爲了便於閱讀,開發人員通常決定明確聲明<ClassName>Id,以便其他開發人員明確知道它在那裏(不依賴於約定而不是配置)。例如,教程就是這種情況,因爲他們想要說清楚。

實體框架足夠智能,可以使用現有的<ClassName>Id(如果已經明確聲明)。因此,處理對這個主題的其他迴應,它不會導致不一致的狀態。另外,從性能的角度來看,它仍然適合懶惰加載模式,因爲預加載int(在這種情況下,ID)仍然非常快(甚至與預加載整個對象的程度相差甚遠)。

相關問題