EF Core 迁移从其他上下文添加表

Posted

技术标签:

【中文标题】EF Core 迁移从其他上下文添加表【英文标题】:EF Core Migration Adding Tables from Other Contexts 【发布时间】:2021-09-28 09:30:14 【问题描述】:

我正在尝试在两个表(CustomerProfile 和 ProviderProfile)和一个主 ASP.NET Core IdentityUser 表(AppUser)之间创建 1..1 关系。当我运行迁移时,所有表都是从 AppUser 模式(用户)内的每个模式(3 个表中的每一个都有自己的模式设置)生成的。以下是IdentityContext 的配置方式:

public class IdentityContext : IdentityDbContext<AppUser, AppRole, string>

    private const string schema = "Users";

    
    public DbSet<CustomerProfile> CustomerProfile  get; set; 
    public DbSet<ProviderProfile> ProviderProfile  get; set; 

   public override void OnModelCreating(ModelBuilder builder)
   
        base.OnModelCreating(builder);
        builder.HasDefaultSchema(schema);

        builder.Entity<AppUser>()
            .HasOne(x => x.ProviderProfile)
            .WithOne(x => x.User)
            .HasForeignKey<ProviderProfile>(x => x.UserId);
        
        builder.Entity<AppUser>()
            .HasOne(x => x.CustomerProfile)
            .WithOne(x => x.User)
            .HasForeignKey<ProviderProfile>(x => x.UserId);
    

这里是 AppUser (IdentityUser) 类定义:

public class AppUser : IdentityUser

    public bool IsServiceProvider  get; set; 
    public virtual CustomerProfile CustomerProfile  get; set; 
    public virtual ProviderProfile ProviderProfile  get; set; 

当我运行迁移时,数据库用户架构作为一大堆表形成了其他 DbContexts,这些 DbContexts 又持有对 CustomerProfileProviderProfile 的引用,这些表也包含所有这些表(它们应该存在的地方)。

提供更多详细信息:CustomerProfile 和 ProviderProfile 都有自己的 DbContext,并引用其中的几个其他表(这些相关表属于每个配置文件的架构)。每个配置文件中的表与配置文件类属于相同的模式。这些实体/表是在它们不属于的身份模式(用户)中生成的罪魁祸首。

有 3 种模式:

    用户(IdentityContext - 用户架构) 客户(CustomersContext - 客户架构) 提供者(ProvidersContext - 提供者架构)

因此,用户上下文与客户和提供者表具有 1..1 关系。

CustomersContext 有几个与客户相关的表 ProvidersContext 有几个与提供者相关的表

Customers + Providers 上下文中的表被转储到 Users (IdentityContext) 架构中

【问题讨论】:

您能否详细描述您的问题,您是否迁移以生成其他 dbcontexts? OnModelCreating 中忽略对其他实体的引用不起作用吗? @Yinqiu - 更详细地更新了问题。 @abdusco - 我想我可以将它们添加到忽略列表中 - 但这真的有必要吗?我认为 EF 足够复杂,可以知道它们不是架构的一部分。 @abdusco - 这似乎有效。您要添加它作为答案,我会将其标记为解决方案吗? 【参考方案1】:

每当 EF 在实体类 A 中遇到引用 B 类的属性时,它都会添加一个连接两者的新关系。

class Student 
    public School School  get; set;  // <-- many-to-one relation
    public List<Course> Courses  get; set;  // <-- many-to-many relation
    // ...

这发生在by convention,不需要开发人员参与。

默认情况下,当在类型上发现导航属性时,将创建关系。如果属性指向的类型不能被当前数据库提供者映射为标量类型,则该属性被视为导航属性。

如果您想阻止 EF Core 将这些属性解释为关系,您需要明确告诉 ignore those properties,EF 不会尝试将它们映射到 DB。

protected override void OnModelCreating(ModelBuilder modelBuilder)

    modelBuilder.Entity<AppUser>()
        .Ignore(e => e.CustomerProfile);
    // ...

【讨论】:

我想我仍然可以调用关系并使用 EF 获取 CustomerProfiles 吗?即 - context.AppUser.Profiles.Where(x =&gt; x.Id == 1); Profile 实体注册的上下文中更像context.Profiles.Wherecontext.Set&lt;Profile&gt;().Where

以上是关于EF Core 迁移从其他上下文添加表的主要内容,如果未能解决你的问题,请参考以下文章

从 EF Core 5 迁移到 EF Core 6 时出错

如何跳过ef core中的某些迁移?

EF Core 迁移:在存在时删除唯一约束

我可以避免在 EF Core 中使用迁移吗?

[EF Core]数据迁移

带有 UWP 的 EF Core - Visual Studio 19