2013-06-06 26 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

相关问题