在尝试创建迁移时,您如何找到或知道 "non-owned" 实体类型在哪里?

How do you find or know where the "non-owned" entity type when trying to create a migration?

我有以下 类:

  1. 拥有 CreditCard 的 JobSeeker 具有 CreditCardType

     public class JobSeeker : Entity
     {
         private readonly List<CreditCard> _creditCards;        
         public IEnumerable<CreditCard> CreditCards => _creditCards.AsReadOnly();
     }
    
     public class CreditCard : Entity
     {
         public CreditCardType CardType { get { return CreditCardType.From(_creditCardTypeID); } private set { } }
         private readonly int _creditCardTypeID;}
    
    
     public class CreditCardType : Enumeration
     {
         public static readonly CreditCardType Amex = new CreditCardType(1, nameof(Amex).ToLowerInvariant());
    
         public static readonly CreditCardType Visa = new CreditCardType(2, nameof(Visa).ToLowerInvariant());
    
         public static readonly CreditCardType MasterCard = new CreditCardType(3, nameof(MasterCard).ToLowerInvariant());
    
         public static IEnumerable<CreditCardType> List() => new[] { Amex, Visa, MasterCard };}
    

我的 DBContext 配置是:

class JobSeekerEntityTypeConfiguration : IEntityTypeConfiguration<JobSeeker>
{
    public void Configure(EntityTypeBuilder<JobSeeker> jsConfiguration)
    {
        if (jsConfiguration == null)
        {
            throw new ArgumentNullException(nameof(jsConfiguration));
        }

        // Build the model
        jsConfiguration.OwnsOne(s => s.CompleteName);
        jsConfiguration.OwnsOne(s => s.HomeAddress);
        jsConfiguration.OwnsOne(s => s.BillingAddress);
        jsConfiguration.OwnsOne(s => s.EmAddress);
        jsConfiguration.OwnsOne(s => s.PersonalPhoneNumber);

        jsConfiguration.OwnsMany(a => a.CreditCards);

        //jsConfiguration.HasMany<CreditCard>().WithOne(JobSeeker).OnDelete(DeleteBehavior.Restrict);


        jsConfiguration.Property<DateTime>("CreatedDate");
        jsConfiguration.Property<DateTime>("UpdatedDate");
    }
}

class CreditCardTypeEntityTypeConfiguration : IEntityTypeConfiguration<CreditCard>
{
    public void Configure(EntityTypeBuilder<CreditCard> ccConfiguration)
    {
        if (ccConfiguration == null)
        {
            throw new ArgumentNullException(nameof(ccConfiguration));
        }

        // Build the model
        ccConfiguration.HasOne(o => o.CardType).WithMany().HasForeignKey("_creditCardTypeID");

        ccConfiguration.Property<DateTime>("CreatedDate");
        ccConfiguration.Property<DateTime>("UpdatedDate");

    }
}

class CreditCardEntityTypeConfiguration : IEntityTypeConfiguration<CreditCardType>
{
    public void Configure(EntityTypeBuilder<CreditCardType> cctConfiguration)
    {
        if (cctConfiguration == null)
        {
            throw new ArgumentNullException(nameof(cctConfiguration));
        }

        // Build the model
        cctConfiguration.ToTable("CreditCardTypes");

        cctConfiguration.HasKey(o => o.Id);

        cctConfiguration.Property(o => o.Id)
            .HasDefaultValue(1)
            .ValueGeneratedNever()
            .IsRequired();

        cctConfiguration.Property(o => o.Name)
            .HasMaxLength(200)
            .IsRequired();

        cctConfiguration.HasData(
                new { Id = 1, Name = "Amex" },
                new { Id = 2, Name = "Visa" },
                new { Id = 3, Name = "MasterCard" });


    }
}

我的数据库上下文是:

public class JobSeekerContext : DbContext, IUnitOfWork
{
    private static readonly Type[] EnumerationTypes = { typeof(CreditCardType) };

    public const string DEFAULT_SCHEMA = "jobseeker";

    private readonly ILoggerFactory MyConsoleLoggerFactory;

    private readonly IMediator Mediator;

    public DbSet<JobSeeker> JobSeekers { get; set; }

    public DbSet<CreditCard> CreditCards { get; set; }
    public DbSet<CreditCardType> CreditCardTypes { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        if (modelBuilder == null)
        {
            throw new ArgumentNullException(nameof(modelBuilder));
        }

        // Build the model
        modelBuilder.ApplyConfiguration(new CreditCardTypeEntityTypeConfiguration());
        modelBuilder.ApplyConfiguration(new CreditCardEntityTypeConfiguration());
        modelBuilder.ApplyConfiguration(new JobSeekerEntityTypeConfiguration());

}

当我 运行 迁移时,出现以下错误:“类型 'CreditCard' 无法标记为拥有,因为已存在同名的非拥有实体类型。”

CreditCard 在哪里标记为非拥有?

Where is CreditCard marked as non-owned?

JobSeekerContext这里

public DbSet<CreditCard> CreditCards { get; set; }

这里

modelBuilder.ApplyConfiguration(new CreditCardTypeEntityTypeConfiguration());

和整个(误导性命名)CreditCardTypeEntityTypeConfiguration class 因为它是 IEntityTypeConfiguration<CreditCard>.


Owned entity types 是通过 owner.

配置、查询和更新的特殊实体

以下是当前 EF Core 文档的 By-design restrictions 部分的摘录:

  • You cannot create a DbSet<T> for an owned type.
  • You cannot call Entity<T>() with an owned type on ModelBuilder.

请注意,应用 IEnityTypeConfiguration<T> class 等同于在 ModelBuilder 上调用 Entity<T>()

所以你违反了上述两个限制。

你需要做的是

  1. 从上下文中删除 DbSet<CreditCard> 属性
  2. 删除CreditCardTypeEntityTypeConfigurationclass和相应的ApplyConfiguration调用
  3. 通过 OwnsMany 方法使用构建器 provided/returned 将 CreditCard 配置代码移动到所有者 JobSeeker 配置中。例如
jsConfiguration.OwnsMany(a => a.CreditCards, ccConfiguration =>
{
    // Build the model
    ccConfiguration.HasOne(o => o.CardType).WithMany().HasForeignKey("_creditCardTypeID");
    
    ccConfiguration.Property<DateTime>("CreatedDate");
    ccConfiguration.Property<DateTime>("UpdatedDate");
});