EF Core 3:无法将CLR属性“ Number”添加到实体类型“ CHSIMTBase”,因为它是在CLR类型“合同”上声明的

安东尼·布伦尼埃(AnthonyBrenelière)

我需要基于合同编号在两个类ContractItemContract之间创建关系

这种关系:

  1. 针对派生类合同
  2. 不使用Contract的名为Reference的主键,但使用Number

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

但是Contract是抽象基类CHSIMTBase的派生类

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

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

  • CHSIMTBase不是合约
  • CHSIMTBase是抽象的(此类型没有标识符)

重现步骤

这是重现该错误的模型和上下文:


    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 IDE:Visual Studio 2019

安东尼·布伦尼埃(AnthonyBrenelière)

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

对于实体Contract,主键为Reference,与ContractItem的关系中使用的替代键Number

因此,解决方案是将备用键的属性Number从派生类Contract移到基类CHSIMTBase

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

Related 相关文章

热门标签

归档