EF Core 6:查找中间表的名称

Posted

技术标签:

【中文标题】EF Core 6:查找中间表的名称【英文标题】:EF Core 6: Find name of Intermediate table 【发布时间】:2022-01-19 19:07:28 【问题描述】:

从 EF Core 5 开始,无需显式定义中间表即可轻松生成多对多表。但是,我希望能够获得两个实体之间自动生成的中间表的名称。例如,假设我有两个实体:

public class Foo

    public int FooId  get; set; 
    public ICollection<Bar> Bars  get; set; 


public class Bar

    public int BarId  get; set; 
    public ICollection<Foo> Foos  get; set; 

我创建了一个包含这两个实体的 DbContext,创建了一个迁移,然后将其应用到我的数据库中,我希望生成三个表:

Foos Bars FooBars

有没有办法,给定FooBar(或Foo.BarsBars.Foos),找到自动生成的表名FooBars的名称?

【问题讨论】:

你试过检查 IModel 吗? context.Model 是的,我今天下午一直在探索 IModel,但还没有找到我要找的东西。 【参考方案1】:

不确定这是否有帮助,但您始终可以选择命名包含多对多关系的中间表。

因此,如果让 EF Core 处理中间表,则不能指定名称,但可以在定义时调用 UsingEntity&lt;T&gt; 以指定表名。

public class AppDbContext : DbContext

    public DbSet<Foo> Foos  get; set; 
    public DbSet<Bar> Bars  get; set; 

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    
        optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=FoobarmanytomanySample;Trusted_Connection=True;MultipleActiveResultSets=true")
                      .UseLazyLoadingProxies();
    

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    
        modelBuilder.Entity<Entry>()
                    .HasMany(x => x.Foos)
                    .WithMany(x => x.Bars)
                    .UsingEntity<Dictionary<string, object>>(
                        "FooBars",
                        x => x.HasOne<Tag>().WithMany(),
                        x => x.HasOne<Entry>().WithMany());
    

【讨论】:

我希望避免这种情况,但我很欣赏这个建议。谢谢。【参考方案2】:

终于找到了办法。没有异常处理,我不确定它有多脆弱,但它适用于我的 DbContext。一个例子:

public class Foo

    public int FooId  get; set; 
    public ICollection<Bar> Bars  get; set; 


public class Bar

    public int BarId  get; set; 
    public ICollection<Foo> Foos  get; set; 


public class AppDbContext : DbContext

    public DbSet<Foo> Foos  get; set; 
    public DbSet<Bar> Bars  get; set; 

    public string GetIntermediateTableNameForEntityProperty(Type entity, string propertyName)
    
        IEntityType entityType = base.Model.FindEntityType(entity);
        ISkipNavigation propSkipNavigation = entityType.GetSkipNavigations().Single(x => string.Equals(x.Name, propertyName));
        IForeignKey foreignKey = propSkipNavigation.ForeignKey;
        IProperty foreignKeyProperty = foreignKey.Properties.Single();
        string intermediateTableName = foreignKeyProperty.DeclaringEntityType.Name;
        return intermediateTableName;
    

用法:

public class Baz

    private readonly AppDbContext _appDbContext;

    public Baz(AppDbContext appDbContext)
    
        _appDbContext = appDbContext;
    

    public void SomeMethod()
    
        var intermediateTableName = _appDbContext.GetIntermediateTableNameForEntityProperty(typeof(Foo), nameof(Foo.Bars));
        // intermediateTableName = "FooBars"
    

【讨论】:

以上是关于EF Core 6:查找中间表的名称的主要内容,如果未能解决你的问题,请参考以下文章

EF Core 中的软删除中间表行

更改生成的联接表的名称(多对多)-EF Core 5

EF中间表操作

其他两个中间人之间的中间表的正确名称

EF Core codefirst数据迁移

折半查找两种实现