2013-06-06 53 views
11

是否有可能在實體框架6中使用代碼優先和註釋創建單向多對多關聯?例如:實體框架6代碼優先 - 通過註釋多對多的方式

class Currency 
{ 
    public int id { get; set; } 
} 

class Country 
{ 
    public int id { get; set; } 

    // How i can annotate this property to say EF that it is many-to-many 
    // and it should create mapping table? 
    // I don't need navigation property to Country in Currency class! 
    public virtual IList<Currency> currencies { get; set; } 
} 

在支持Java + JPA批註我可以實現我所需要的是這樣的:

@OneToMany 
@JoinTable(name = "MAPPING_TABLE", joinColumns = { 
    @JoinColumn(name = "THIS_ID", referencedColumnName = "ID") 
}, inverseJoinColumns = { 
    @JoinColumn(name = "OTHER_ID", referencedColumnName = "ID") 
}) 

是這樣,EF具有相同的功能?

回答

0

我想你想學習如何將關係從EF代碼第一個實體中分離出來。我已經在here關於這個問題開始了一個話題。我想將關係對象與實體分開,並使用部分類。在我的問題中,我想學習如何按班級分開部分班級。但不能。

當我使用NHibernate時,我在這裏使用XML映射和創建關係,在java平臺中是一樣的。但我認爲實體框架還沒有準備好。

30

您可以通過使用Fluent API明確指定關係來做到這一點。重寫你的DbContext類的OnModelCreating()方法,並在重寫指定映射表,像這樣的細節:

class MyContext : DbContext 
{ 
    public DbSet<Currency> Currencies { get; set; } 
    public DbSet<Country> Countries { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Country>() 
      .HasMany(c => c.Currencies) 
      .WithMany()     // Note the empty WithMany() 
      .Map(x => 
      { 
       x.MapLeftKey("CountryId"); 
       x.MapRightKey("CurrencyId"); 
       x.ToTable("CountryCurrencyMapping"); 
      }); 

     base.OnModelCreating(modelBuilder); 
    } 
} 

注意 - 反正在我的快速測試 - 加載時,你將不得不Include()貨幣屬性已經在列表填充EF對象:

  var us = db.Countries 
         .Where(x => x.Name == "United States") 
         .Include(x=>x.Currencies) 
         .First(); 

編輯

如果你真的想要做的一切與數據註釋,而不是用流利的話,那麼你可以在J MODEL oin表中明確指出elsewhere。雖然這種方法存在各種可用性缺點,但似乎Fluent方法是最好的方法。魔術在後臺連接表 -

class Country 
{ 
    public int Id { get; set; } 
    public virtual ICollection<CountryCurrency> CountryCurrencies { get; set; } 
} 

class Currency 
{ 
    public int Id { get; set; } 
} 

class CountryCurrency 
{ 
    [Key, Column(Order=0)] 
    public virtual int CountryId { get; set; } 
    [Key, Column(Order=1)] 
    public virtual int CurrencyId { get; set; } 

    public virtual Country Country { get; set; } 
    public virtual Currency Currency { get; set; } 
} 
+0

謝謝......有沒有可能只使用註釋來執行此配置? – Anton

+0

我認爲你可以做的最好的做法是明確建模連接表。因此,將CountryCurrency類與您的其他EF對象一起製作,然後用「ICollection 」替換Country對象中的「currency」屬性。但是,這存在可用性方面的缺點,因爲EF不會爲您自動在後臺執行JOIN。 –

+0

奇怪的是,沒有辦法用屬性來做到這一點。 EF是一團糟。 – yonexbat

0

可以在EF 6

public class Country 
{ 
    public int ID {get;set;} 

    public virtual ICollection<Currency> Currencys {get;set;}//don't worry about the name,  pluralisation etc 


} 

public class Currency 
{ 

    public int ID {get;set;} 

    public virtual ICollection<Country> Countrys {get;set;}//same as above - 

} 

編譯,運行和變戲法似的在代碼中做到這一點首先很容易。取決於命名約定是否打擾你。我個人認爲,如果你先做代碼,你應該在代碼中完成所有的工作。有些人更喜歡註釋,有些更喜歡流利的API--使用任何你喜歡的。

+0

問題是關於單向導航的明確問題。向貨幣添加國家消除了這一限制。 – KyorCode

+0

我聽到你在說什麼,但從我可以告訴的方式導航屬性有違代碼第一原則。將這兩個集合放入的缺點是什麼?它變得性能較差嗎? – Will

相關問題