You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Angular表单插入.NET后端自增ID报错问题

解决自增列插入错误:Angular + .NET API 实战方案

问题根源

错误提示 Cannot insert explicit value for identity column in table 'StockFeed' when IDENTITY_INSERT is set to OFF,本质是SQL Server不允许手动给自增列赋值。

虽然Angular表单里没加Id字段,但你的.NET Stock模型包含Id属性,默认值为0。Angular在发送请求时会把这个0一起序列化到请求体中,.NET接收后,EF会尝试将这个0插入到自增的Id列,从而触发错误。

另外注意:你的Stock模型里有Production_date字段,但Angular表单未包含该控件,发送请求时这个字段会缺失,可能导致后端ModelState验证失败,需要同步处理。


推荐解决方案:使用DTO(数据传输对象)

这是前后端分离的标准做法,精确控制前端传入的字段,避免实体类直接暴露,提升安全性和可维护性。

步骤1:创建StockCreateDto类

在.NET项目中新建一个DTO类,只包含前端需要传入的字段:

namespace AuthAPI.Dtos
{
    public class StockCreateDto
    {
        public long Company_id { get; set; }
        public long Stockfeedtype_id { get; set; }
        public int Installed_capacity { get; set; }
        public int Current_production { get; set; }
        public int Local_supply { get; set; }
        public int Exported { get; set; }
        public DateTime Production_date { get; set; }
    }
}

步骤2:标记模型的自增属性

修改Stock模型,明确标记Id为数据库自增列:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace AuthAPI.Models
{
    public class Stock
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)] // 标记为自增列
        public int Id { get; set; }
        
        public long Company_id { get; set; }
        public long Stockfeedtype_id { get; set; }
        public int Installed_capacity { get; set; }
        public int Current_production { get; set; }
        public int Local_supply { get; set; }
        public int Exported { get; set; }
        public DateTime Production_date { get; set; }
    }
}

步骤3:修改API控制器接收DTO

更新控制器代码,接收DTO并转换为实体类:

[HttpPost("addfeed")]
public async Task<IActionResult> CreateStockFeed([FromBody] StockCreateDto stockFeedDto)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    // 将DTO转换为Stock实体
    var stockFeed = new Stock
    {
        Company_id = stockFeedDto.Company_id,
        Stockfeedtype_id = stockFeedDto.Stockfeedtype_id,
        Installed_capacity = stockFeedDto.Installed_capacity,
        Current_production = stockFeedDto.Current_production,
        Local_supply = stockFeedDto.Local_supply,
        Exported = stockFeedDto.Exported,
        Production_date = stockFeedDto.Production_date
    };

    _dbContext.StockFeed.Add(stockFeed);
    await _dbContext.SaveChangesAsync();

    return CreatedAtAction(nameof(GetStockFeedById), new { id = stockFeed.Id }, stockFeed);
}

步骤4:补充Angular的Production_date字段

在Angular表单中添加日期控件,或在发送请求时自动生成日期:

// 修改组件的onInsert方法
onInsert() {
  if(this.stockFeedForm.valid){
    const requestData = { 
      ...this.stockFeedForm.value,
      production_date: new Date().toISOString() // 自动生成当前日期
    };

    this.auth.addfeed(requestData)
     .subscribe({
      next:(res)=>{
        alert(res.message);
        this.stockFeedForm.reset();
        this.router.navigate(['stockFeed']);
      },
      error:(err)=>{
        alert(err.message);
      }
     });
  }else{
    validateForm.validateAllFormFields(this.stockFeedForm);
    alert("表单验证不通过");
  }
}

临时解决方案:Angular端手动移除Id字段

如果不想修改.NET端,可在发送请求前删除可能存在的Id字段:

onInsert() {
  if(this.stockFeedForm.valid){
    const requestData = { ...this.stockFeedForm.value };
    delete requestData.id; // 移除Id字段
    requestData.production_date = new Date().toISOString();

    this.auth.addfeed(requestData)
     .subscribe({
      next:(res)=>{
        alert(res.message);
        this.stockFeedForm.reset();
        this.router.navigate(['stockFeed']);
      },
      error:(err)=>{
        alert(err.message);
      }
     });
  }else{
    validateForm.validateAllFormFields(this.stockFeedForm);
    alert("表单验证不通过");
  }
}

内容的提问来源于stack exchange,提问作者NewbieNerd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 23:04:57