13

是否可以在实体框架 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 是否具有相同的功能?

4

3 回答 3

30

您可以通过使用 Fluent API 显式指定关系来做到这一点。覆盖类的OnModelCreating()方法DbContext,并在覆盖中指定映射表的详细信息,如下所示:

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 对象以填充列表时,您必须使用 Currencies 属性:

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

编辑

如果您真的想用数据注释做所有事情,并且根本不使用 Fluent,那么您可以像其他地方指出的那样显式地为连接表建模。但是,这种方法存在各种可用性缺点,因此 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; }
}
于 2013-06-06T15:06:33.390 回答
0

我认为您想学习如何将关系与 EF 代码优先实体分开。我在这里开始了一个关于这个问题的话题。我想将关系对象与实体分开,并且我使用了部分类。在我的问题中,我想学习如何通过类 bilrary 来区分部分类。但不能。

当我使用 NHibernate 时,我在这里使用 XML 映射和创建关系,在 java 平台中也是一样的。但我认为实体框架还没有准备好。

于 2013-06-06T05:57:10.797 回答
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 - 

}

编译它,运行它,嘿,presto - 后台魔术连接表。取决于命名约定是否打扰您。我个人认为,如果你先做代码,你应该在代码中做所有的事情。有些人喜欢注解,有些人喜欢流畅的 API - 使用你喜欢的任何一个。

于 2014-04-14T12:24:30.880 回答