【问题标题】:Identity and inheritance Error On Migration: A key cannot be configured on 'Person' because it is a derived type迁移时的身份和继承错误:无法在“人员”上配置密钥,因为它是派生类型
【发布时间】:2019-02-18 06:40:09
【问题描述】:

我正在使用 EF Core 和 Identity。 我创建了一个简单的应用程序:

public class Program
{
    static void Main(string[] args)
    {
    }
}


public class User : IdentityUser
{
}

public class Person : User
{
}

public class Document
{
    public int Id { get; set; }

    public User Owner { get; set; }
}


public class ApplicationDbContext : IdentityDbContext<Person>
{
    public DbSet<Person> Person { get; set; }
    public DbSet<Document> Document { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(@"Server=.\;Database=EFCoreDemo;Trusted_Connection=True;MultipleActiveResultSets=true");
    }
}

当我想添加迁移时它给了我这个错误:

无法在“Person”上配置键,因为它是派生类型。必须在根类型“用户”上配置密钥。如果您不打算将“用户”包含在模型中,请确保它不包含在上下文的 DbSet 属性中、在对模型构建器的配置调用中引用或从包含的类型的导航属性中引用在模型中。

我已经测试了这些更改:

1) 如果 Owner 变为 Person 类型,则会出现错误,但这对我来说不是一个选项,因为实际上 User 和 Document 在一个库中,而我的最终应用程序使用该库,而 Person 在应用程序中。

2) 如果 ApplicationDbContext 继承自 DbContext 则会出现错误。

有没有可用的解决方法?

【问题讨论】:

  • 当从IdentityDbContext&lt;Person&gt; 继承时,为什么你甚至还有DbSet&lt;Person&gt; 会给你这个?
  • @DavidG 我已经删除了,但没有效果。
  • 也许你可以尝试用外键将 Person 链接到用户,并让这个外键成为 Person 主键的一部分
  • 由于你的根实体是User(因为需要public User Owner { get; set; }),你的上下文应该派生自IdentityDbContext&lt;User&gt;
  • 最好的解决方案是不要混合上下文。只需将 person 表添加到 business context 中,该表具有链接到当前用户的外键字段(例如,基于 sub 声明),而不是“真正的”数据库关系。

标签: c# asp.net-core asp.net-identity entity-framework-core


【解决方案1】:

对于使用PersonIdentityDbContext 而不更改Document,您可以从Document 实现一个新模型,并将其更改为Person

    public class ApplicationDbContextTest : IdentityDbContext<Person>
{
    public DbSet<MyDocument> Document { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFCoreDemo;Trusted_Connection=True;MultipleActiveResultSets=true");
    }
}
public class User : IdentityUser
{
}

public class Person : User
{
}
public class MyDocument:Document
{
    public new Person Owner { get; set; }
}
public class Document
{
    public int Id { get; set; }

    public User Owner { get; set; }
}

【讨论】:

  • 我喜欢你的解决方案,它似乎欺骗了 EF,而且当我调用 .Include(d => d.Owner) 时,它会加载一个人并设置 MyDocument.Owner 的值。跨度>
  • @HamedH 如果可行,您介意接受它作为答案吗?
  • 这可以用作简单情况的解决方案,但缺点是每个模型都需要新的类,对于更复杂的情况不适合。我目前使用您的解决方案,但想知道是否可以在没有类 MyDocument 的情况下完成
  • 从基实体派生时随时抛出异常,但在正在构建的 EE 模型中的某处引用了基类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-11
  • 1970-01-01
  • 1970-01-01
  • 2015-01-20
  • 2022-06-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多