首页 > 解决方案 > 实体类型对应的 CLR 类型不能实例化 Table-per-type

问题描述

使用 EFCore 5

我一直在尝试按照 Microsoft 教程在模型类中创建一个可能引用其他两个类的字段。

就我而言,我有一个抽象的 Credentials 类和两个子类:ClientCredentialsAccessKeyCredentials。有一个组织类包含对凭据的引用,并且可以使用任何子类来实例化对象。

我希望可以选择使用哪种类型的凭据。

但是,我遇到了一个错误:

System.InvalidOperationException: The corresponding CLR type for entity type 'Credentials' cannot be instantiated, and there is no derived entity type in the model that corresponds to a concrete CLR type.
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelValidator.ValidateClrInheritance(IModel model, IEntityType entityType, HashSet`1 validEntityTypes)
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelValidator.ValidateClrInheritance(IModel model, IDiagnosticsLogger`1 logger)
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger)
   at Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger)
   at Microsoft.EntityFrameworkCore.SqlServer.Internal.SqlServerModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger)
   at Microsoft.EntityFrameworkCore.Metadata.Conventions.ValidatingConvention.ProcessModelFinalized(IModel model)
   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnModelFinalized(IModel model)
   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.OnModelFinalized(IModel model)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.Model.FinalizeModel()
   at Microsoft.EntityFrameworkCore.ModelBuilder.FinalizeModel()
...

我不太清楚这里有什么问题。我一直在尝试遵循一些文档页面,但没有成功。

以防万一,链接是:

这是我的代码示例:

凭据.cs

public abstract class Credentials
{
    public Credentials()
    {
        this.CreatedOn = DateTime.Now;
    }

    [Key]
    public Guid Id { get; set; }
    public int TypeId { get; set; }


    public DateTime CreatedOn { get; set; }
    public DateTime UpdatedOn { get; set; }

    [ForeignKey("TypeId")]
    public virtual CredentialsType Type { get; set; }
}

ClientCredentials.cs

public class ClientCredentials : Credentials
{
    [Required]
    public string ClientId { get; set; }
    public string ClientSecret { get; set; }
}

AccessKeyCredentials.cs

public class AccessKeyCredentials : Credentials
{
    [Required]
    public string Username { get; set; }
    public string AccessKey { get; set; }
}

组织.cs

public class Organization
    {
        public Organization()
        {
            this.CreatedOn = DateTime.Now;
        }

        [Key]
        public Guid Id { get; set; }
        [Required]
        public string Name { get; set; }
        public string Country { get; set; }
        public string City { get; set; }
        public string Address { get; set; }
        public string PhoneNumber { get; set; }
        public string AdditionalInformation { get; set; }
        public string BusinessCentralInstanceUrl { get; set; }

        public Guid BusinessCentralCredentialsId { get; set; }


        public DateTime CreatedOn { get; set; }
        public DateTime UpdatedOn { get; set; }

        public virtual IList<UserIdentity> Users { get; set; }

        [ForeignKey("BusinessCentralCredentialsId")]
        public virtual Credentials BusinessCentralCredentials { get; set; }
    }

数据库上下文.cs

public class OrganizationDbContext : DbContext, IOrganizationDbContext
{
    public DbSet<Organization> Organizations { get; set; }
    public DbSet<Credentials> Credentials { get; set; }
    public DbSet<CredentialsType> CredentialTypes { get; set; }

    public OrganizationDbContext(DbContextOptions<OrganizationDbContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<Organization>(entity =>
        {
            entity.ToTable(TableConsts.Organizations);

            entity.HasKey(x => x.Id);

            entity.HasMany(x => x.Users)
                .WithOne(x => x.Organization)
                .OnDelete(DeleteBehavior.ClientSetNull);

            //entity.HasOne(x => x.BusinessCentralCredentials)
            //    .WithOne()
            //    .OnDelete(DeleteBehavior.ClientSetNull);
        });

        //modelBuilder.Entity<Credentials>(entity =>
        //{
        //    entity.ToTable(TableConsts.BusinessCentralCredentials);
        //    entity.HasKey(x => x.Id);

        //    entity.HasOne(x => x.Type)
        //        .WithOne()
        //        .OnDelete(DeleteBehavior.ClientSetNull);
        //});

        //modelBuilder.Entity<Credentials>().ToTable(TableConsts.BusinessCentralCredentials);

        modelBuilder.Entity<ClientCredentials>().ToTable(TableConsts.BusinessCentralClientCredentials);

        modelBuilder.Entity<AccessKeyCredentials>().ToTable(TableConsts.BusinessCentralAccessKeyCredentials);

        modelBuilder.Entity<CredentialsType>(entity =>
        {
            entity.ToTable(TableConsts.BusinessCentralCredentialTypes);
            entity.HasKey(x => x.Id);
        });

        modelBuilder.Entity<UserIdentity>()
            .ToTable(TableConsts.AspNetUsers, t => t.ExcludeFromMigrations());
    }
}

希望您可以帮助找出解决此问题的方法。

先感谢您。

UPD:我可以创建迁移并应用它而不会出现任何错误。当我启动我的应用程序时发生错误。

标签: c#entity-frameworkentity-framework-core

解决方案


推荐阅读