c# - 实体类型对应的 CLR 类型不能实例化 Table-per-type
问题描述
使用 EFCore 5
我一直在尝试按照 Microsoft 教程在模型类中创建一个可能引用其他两个类的字段。
就我而言,我有一个抽象的 Credentials 类和两个子类:ClientCredentials和AccessKeyCredentials。有一个组织类包含对凭据的引用,并且可以使用任何子类来实例化对象。
我希望可以选择使用哪种类型的凭据。
但是,我遇到了一个错误:
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()
...
我不太清楚这里有什么问题。我一直在尝试遵循一些文档页面,但没有成功。
以防万一,链接是:
- https://docs.microsoft.com/en-us/ef/core/modeling/inheritance
- https://weblogs.asp.net/manavi/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-2-table-per-type-tpt
这是我的代码示例:
凭据.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:我可以创建迁移并应用它而不会出现任何错误。当我启动我的应用程序时发生错误。
解决方案
推荐阅读
- google-app-engine - 不能通过 IAP 将 SSH 隧道连接到 App Engine 实例吗?
- unit-testing - > 未能应用插件“com.android.library”。> 无法添加任务“unitTestCoverage”,因为具有该名称的任务已存在
- python - 如果设置返回类型,Python 中的 VS Code 会更改代码的文本颜色
- refactoring - 通过示例重构 - 需要参考
- java - 如何在 Java 8 中最好地使用有序 Map
- vmware - 通过 API 删除 VMWare 模板
- c# - 在 C# MVP 中处理菜单事件
- r - 比较不同 R 包版本之间的 NAMESPACE 文件
- powerquery - 将表中的两列合并为记录类型的新列,以便我可以在其上进行透视
- python - 1045, "拒绝访问用户 'root'@'localhost' (使用密码: NO)"