实体框架核心-无法添加子记录

时间:2019-09-27 14:32:42

标签: c# asp.net-core entity-framework-core

我有一个父子关系,并且我无法在EF Core中使用脚手架命令,因为子表没有键。我不允许添加密钥,所以我被体系结构所困扰。

保存更改时,出现以下内部异常: 无效的列名“ NewBusinessMasterNbTransactionId”

Startup.cs中的代码:

  public void ConfigureServices(IServiceCollection services)
  {
    var connection = Configuration.GetSection("SqlConnection1").Value;
    services.AddScoped<IDharma, DharmaRepo>();
    services.AddDbContext<DharmaContext>(options => options.UseSqlServer(connection));
  }

DharmaContext中的代码(我删除了大多数数据列以使其更短):

 public partial class DharmaContext : DbContext
 {
    public DharmaContext()
    {
    }

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

    public virtual DbSet<NewBusinessMaster> NewBusinessMaster { get; set; }
    public virtual DbSet<NewBusinessDetail> NewBusinessDetail { get; set; }


    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.HasAnnotation("ProductVersion", "2.2.4-servicing-10062");
        modelBuilder.Entity<NewBusinessMaster>(entity =>
        {
            entity.HasKey(e => e.NbTransactionId);

            entity.ToTable("NewBusiness_Master");

            entity.Property(e => e.NbTransactionId).HasColumnName("NB_TRANSACTION_ID");

            entity.Property(e => e.NbLob)
                .HasColumnName("NB_LOB")
                .HasMaxLength(2)
                .IsUnicode(false);

        });

        modelBuilder.Entity<NewBusinessDetail>(entity =>
        {
            entity.HasKey(e => e.NbTransactionId);

            entity.ToTable("NewBusiness_Detail");

            entity.Property(e => e.NbTransactionId).HasColumnName("NB_TRANSACTION_ID");
        });
            entity.Property(e => e.NbAgentNumber)
                .IsRequired()
                .HasColumnName("NB_AGENT_NUMBER")
                .HasMaxLength(9)
                .IsUnicode(false);
     }
  }

模型(我删除了大多数数据列以使其更易于阅读):

    public partial class NewBusinessMaster
    {
        public int NbTransactionId { get; set; }
        public string NbLob { get; set; }

        public List<NewBusinessDetail> NewBusinessDetail { get; set; }

        public NewBusinessMaster()
        {
            NewBusinessDetail = new List<NewBusinessDetail>();
        }

    }

    public partial class NewBusinessDetail
    {
        public int NbTransactionId { get; set; }
        public string NbAgentNumber { get; set; }
    }
}

添加和保存记录的代码:

NewBusinessMaster nbMaster = new NewBusinessMaster();
nbMaster.NbLob = "AU";
NewBusinessDetail nbDetailItem = new NewBusinessDetail();
foreach (XElement item in screenH202.Descendants())
{
    nbDetailItem = new NewBusinessDetail();
    if (!string.IsNullOrEmpty(item.Value))
    {
        nbDetailItem.NbAgentNumber = nbMaster.NbAgentNumber;
    }
}
_context.NewBusinessMaster.Add(nbMaster);
 try
 {
    await _context.SaveChangesAsync(); //this line throws the error
 }
 catch (DbUpdateException dbEx)
 {
    throw;
 }

SQL的屏幕截图:

enter image description here

enter image description here

2 个答案:

答案 0 :(得分:0)

根据定义,“实体”是带有标识符的对象。出于某种原因,它称为 Entity 框架,它是用于处理实体的框架,这意味着它们必须具有主键(标识符)。

也就是说,这里可能有几个选项供您选择。首先,EF Core支持所谓的“ owned entities”。这些本质上是值对象(从其值的总和中获取其身份的对象,而不是诸如地址之类的显式标识符),因此不具有显式标识符属性。但是,它们仍然具有主键,即外键,与“拥有”它们的实体建立一对一关系。不过,我不确定您将如何实际搭建一个自有类型。如果您有一个表,其中外键也是主键,则EF Core可能会推断出它是该表的拥有类型,但是如果情况并非如此,仍可能需要在表中添加主键。

唯一的选择是EF Core称为查询类型或keyless entity types(名称在3.0中已更改为无键)。这些实际上是没有主键的表或视图,或者仅仅是函数或存储过程之类的结果,几乎完全符合您的方案。但是,只能读取它们,不能插入或修改它们,这可能不适用于您的方案。我也不确定如何使用脚手架进行管理。无键类型更多是您要手动添加到上下文中的内容,而不是EF Core会为您生成的内容。

答案 1 :(得分:0)

我终于获得了将键添加到子表的权限。这样可以简化代码,我可以使用scaffold命令。

课程:

public partial class NewBusinessMaster
{
    public NewBusinessMaster()
    {
        NewBusinessDetail = new HashSet<NewBusinessDetail>();
    }

    public int NbTransactionId { get; set; }
    public string NbLob { get; set; }
    public string NbReferenceNumber { get; set; }
    public string NbAgentNumber { get; set; }
    public string NbEntryOper { get; set; }
    public string NbEffectiveDate { get; set; }
    public string NbInsName { get; set; }
    public string NbInsNameAddr { get; set; }
    public string NbInsAddr { get; set; }
    public string NbInsCity { get; set; }
    public string NbInsState { get; set; }
    public string NbInsZip { get; set; }
    public string NbInsPhone { get; set; }
    public string NbUploadInd { get; set; }
    public DateTime NbCreateDate { get; set; }
    public string NbLockedBy { get; set; }
    public string NbQuoteId { get; set; }

    public virtual ICollection<NewBusinessDetail> NewBusinessDetail { get; set; }
}


public partial class NewBusinessDetail
{
    public int NewBusinessDetailId { get; set; }
    public int NbTransactionId { get; set; }
    public string NbAgentNumber { get; set; }
    public string NbScreenName { get; set; }
    public string NbFieldName { get; set; }
    public string NbFieldValue { get; set; }
    public DateTime? NbLastUpdated { get; set; }

    public virtual NewBusinessMaster NbTransaction { get; set; }
}

//Context
public partial class DharmaContext : DbContext
{
    public DharmaContext()
    {
    }

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

    public virtual DbSet<NewBusinessDetail> NewBusinessDetail { get; set; }
    public virtual DbSet<NewBusinessMaster> NewBusinessMaster { get; set; }


    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {

    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.HasAnnotation("ProductVersion", "2.2.4-servicing-10062");

        modelBuilder.Entity<NewBusinessDetail>(entity =>
        {
            entity.Property(e => e.NewBusinessDetailId).HasColumnName("NewBusinessDetail_ID");

            entity.Property(e => e.NbAgentNumber)
                .IsRequired()
                .HasColumnName("NB_AGENT_NUMBER")
                .HasMaxLength(9)
                .IsUnicode(false);

            entity.Property(e => e.NbFieldName)
                .HasColumnName("NB_FIELD_NAME")
                .HasMaxLength(8)
                .IsUnicode(false);

            entity.Property(e => e.NbFieldValue)
                .HasColumnName("NB_FIELD_VALUE")
                .HasMaxLength(1000)
                .IsUnicode(false);

            entity.Property(e => e.NbLastUpdated)
                .HasColumnName("NB_LAST_UPDATED")
                .HasColumnType("datetime")
                .HasDefaultValueSql("(getdate())");

            entity.Property(e => e.NbScreenName)
                .HasColumnName("NB_SCREEN_NAME")
                .HasMaxLength(4)
                .IsUnicode(false);

            entity.Property(e => e.NbTransactionId).HasColumnName("NB_TRANSACTION_ID");

            entity.HasOne(d => d.NbTransaction)
                .WithMany(p => p.NewBusinessDetail)
                .HasForeignKey(d => d.NbTransactionId)
                .OnDelete(DeleteBehavior.ClientSetNull)
                .HasConstraintName("MasterDetail_FK");
        });

        modelBuilder.Entity<NewBusinessMaster>(entity =>
        {
            entity.HasKey(e => e.NbTransactionId);

            entity.Property(e => e.NbTransactionId).HasColumnName("NB_TRANSACTION_ID");

            entity.Property(e => e.NbAgentNumber)
                .IsRequired()
                .HasColumnName("NB_AGENT_NUMBER")
                .HasMaxLength(9)
                .IsUnicode(false);

            entity.Property(e => e.NbCreateDate)
                .HasColumnName("NB_CREATE_DATE")
                .HasColumnType("datetime")
                .HasDefaultValueSql("(getdate())");

            entity.Property(e => e.NbEffectiveDate)
                .HasColumnName("NB_EFFECTIVE_DATE")
                .HasMaxLength(6)
                .IsUnicode(false);

            entity.Property(e => e.NbEntryOper)
                .IsRequired()
                .HasColumnName("NB_ENTRY_OPER")
                .HasMaxLength(3)
                .IsUnicode(false);

            entity.Property(e => e.NbInsAddr)
                .HasColumnName("NB_INS_ADDR")
                .HasMaxLength(30)
                .IsUnicode(false);

            entity.Property(e => e.NbInsCity)
                .HasColumnName("NB_INS_CITY")
                .HasMaxLength(30)
                .IsUnicode(false);

            entity.Property(e => e.NbInsName)
                .HasColumnName("NB_INS_NAME")
                .HasMaxLength(30)
                .IsUnicode(false);

            entity.Property(e => e.NbInsNameAddr)
                .HasColumnName("NB_INS_NAME_ADDR")
                .HasMaxLength(30)
                .IsUnicode(false);

            entity.Property(e => e.NbInsPhone)
                .HasColumnName("NB_INS_PHONE")
                .HasMaxLength(12)
                .IsUnicode(false);

            entity.Property(e => e.NbInsState)
                .HasColumnName("NB_INS_STATE")
                .HasMaxLength(2)
                .IsUnicode(false);

            entity.Property(e => e.NbInsZip)
                .HasColumnName("NB_INS_ZIP")
                .HasMaxLength(11)
                .IsUnicode(false);

            entity.Property(e => e.NbLob)
                .HasColumnName("NB_LOB")
                .HasMaxLength(2)
                .IsUnicode(false);

            entity.Property(e => e.NbLockedBy)
                .HasColumnName("NB_LOCKED_BY")
                .HasMaxLength(3)
                .IsUnicode(false);

            entity.Property(e => e.NbQuoteId)
                .HasColumnName("NB_QUOTE_ID")
                .HasMaxLength(15)
                .IsUnicode(false);

            entity.Property(e => e.NbReferenceNumber)
                .IsRequired()
                .HasColumnName("NB_REFERENCE_NUMBER")
                .HasMaxLength(9)
                .IsUnicode(false);

            entity.Property(e => e.NbUploadInd)
                .HasColumnName("NB_UPLOAD_IND")
                .HasMaxLength(1)
                .IsUnicode(false);
        });
    }


//Code to add parent and child
NewBusinessMaster nbMaster = new NewBusinessMaster();
//set each property of master
//...

nbDetailItem = new NewBusinessDetail();
nbMaster.NewBusinessDetail.Add(nbDetailItem);
_context.NewBusinessMaster.Add(nbMaster);
 try
        {
            await _context.SaveChangesAsync();

        }
        catch (DbUpdateException dbEx)
        {

            throw;
        }