繁体   English   中英

EF Core 3:CLR 属性“数字”不能添加到实体类型“CHSIMTBase”,因为它是在 CLR 类型“合同”上声明的

[英]EF Core 3: CLR property 'Number' cannot be added to entity type 'CHSIMTBase' because it is declared on the CLR type 'Contract'

我需要根据合同编号在两个类ContractItemContract之间创建关系。

这种关系:

  1. 针对派生的 class合约
  2. 不使用Contract的名为ReferenceNumber

在关系Contract-ContractIem上使用 HasPrincipalKey(c => c.Number) 时,错误告诉 CLR 属性“数字”不能添加到实体类型“CHSIMTBase”。

但是Contract是抽象基础 class CHSIMTBase 的派生class

我找不到在ContractContractItem之间创建关系的方法。

我试图移动 CHSIMTBase 上的属性 Number 但是

  • CHSIMTBase 不是合同
  • CHSIMTBase 是抽象的(这种类型没有鉴别器)

重现步骤

这是 model 和重现错误的上下文:


    public abstract class CHSIMTBase
    {
        public int Reference { get; set; }
        public string ContractKey { get; set; }
    }

    public class Contract : CHSIMTBase
    {
        public string Number { get; set; }
        public virtual List<CustomerContractLink> CustomerContractLinkRef { get; set; }
    }

    public class CustomerContractLink : EntityLink
    {
        public int Reference { get; set; }
        public Contract Contract { get; set; }
        // public Customer Customer { get; set; }
    }

    public class ContractItem
    {
        public int Code { get; set; }
        public string ContractNumber { get; set; }
        public Contract Contract { get; set; }
       // public Service Service { get; set; }
    }

    public class CoherisContext : DbContext
    {
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<CHSIMTBase>(entity =>
            {
                entity.HasKey(e => e.Reference);
                entity.ToTable("CLIENTS");

                entity
                    .HasDiscriminator(e => e.EntityCode)
                    .HasValue<Customer>( (int) EntityCodes.Customer )
                    .HasValue<Site>(     (int) EntityCodes.Site )
                    .HasValue<Partner>(  (int) EntityCodes.Partner )
                    .HasValue<Contract>( (int) EntityCodes.Contract );

                entity.Property(e => e.Reference)            .HasColumnName("REFERENCE");

            });

            modelBuilder.Entity<Contract>(entity =>
            {
                entity.HasBaseType<CHSIMTBase>();

                entity
                    .HasMany( e => e.CustomerContractLinkRef )
                    .WithOne(c => c.Contract )

                // entity
                //     .HasMany(e => e.ContractItems)
                //     .WithOne(i => i.Contract)
                //     .HasPrincipalKey(i => i.ContractKey)
                //     .HasForeignKey(i => i.ContractNumber);
                //     
                entity.Property(e => e.Number)        .HasColumnName("CL_RUB1");
            });


            modelBuilder.Entity<ContractItem>(entity =>
            {
                entity.ToTable("AF_LINK");
                entity.HasKey(e => e.Code);
                entity.Property(e => e.Code) .HasColumnName("AF_CODE");
                entity.Property(e => e.ContractNumber) .HasColumnName("AF_INFO_COMP1");

                // generate error CLR property 'Number' cannot be added to entity type 'CHSIMTBase' because it is declared on the CLR type 'Contract'.
                entity.HasOne( e => e.Contract)
                    .WithMany().HasPrincipalKey( c => c.Number).HasForeignKey( e => e.ContractNumber );
            });
        }
    }

更多技术细节

EF Core 版本:3.1.6 数据库提供者:Microsoft.EntityFrameworkCore.SqlServer 目标框架:.NET Core 3.0 操作系统:Windows 10 Z581D6381F3F35E4F9D77201ACF887B364:Studio

EF Core 3.1 版本不支持在关系中使用替代键作为外键,如果该映射的替代键是派生 class ( https://github.com/dotnet/efcore/issues/21974 ) 的一部分。

对于实体Contract ,主键是Reference ,与ContractItem的关系中使用的备用键是Number

因此解决方案是将备用密钥的属性Number从派生的 class合同移动到基础 class CHSIMTBase

缺点是所有派生类都可以访问该属性。 如果派生 class 的另一个属性映射到同一列,则必须选择一个通用名称来匹配这两个属性(或使用指向在基类中共享的该属性的派生良好命名属性)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM