实体框架6 code第 - 单向多对多通过注释注释、实体、框架、code

2023-09-04 00:25:00 作者:南筏

是否有可能建立单向多对许多实体框架6协会code第一和说明?例如:

Is it possible to create one-way many-to-many association in entity framework 6 with code first and annotations? Example:

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注解我可以实现我需要这样的:

On Java + JPA annotations i can implement what i need this way:

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

所以,没有EF具有同等功能?

so, does EF have equal features?

推荐答案

您可以通过指定的关系,明确使用流利的API做到这一点。重写你的的DbContext 类的 OnModelCreating()的方法,并在重写指定映射表的详细信息,如本

You can do this by specifying the relationship explicitly using the Fluent API. Override the OnModelCreating() method of your DbContext class, and in your override specify the details of the mapping table like this:

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);
    }
}

需要注意的是 - 在我的快速测试反正 - 你将不得不包括()加载EF对象有填充列表时,货币属性:

Note that - in my quick test anyway - you will have to Include() the Currencies property when loading the EF object to have the list populated:

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

修改

如果你真的想要做的一切用数据注释,而不是用流利的话,那么你可以模拟连接表中明确指出的那样的其他地方。有此方法的各种使用性的缺点,不过,这样看来流利的方法是最好的办法。

If you really want to do everything with Data Annotations, and not use Fluent at all, then you can model the join table explicitly as pointed out elsewhere. There are various usability disadvantages of this approach, though, so it seems the Fluent method is the best approach.

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; }
}