EF Core 6 POST/PUT请求触发System.ArgumentNullException(key参数为空)
多对多关联重复实体时触发System.ArgumentNullException问题
使用POST/PUT提交PredefinedElement数据时,遇到异常:
System.ArgumentNullException: Value cannot be null. (Parameter 'key')
触发场景
通过Radzen Blazor对话框提交数据,当两个PredefinedElement实体关联同一个Market/Product/ActuationType实体时触发该异常。例如关联表Predefinedelement_Market中存在两条记录:
- PredefinedElementId:1、MarketId:1
- PredefinedElementId:2、MarketId:1
异常发生在API控制器调用_dbContext.Add/Update并执行SaveChangesAsync()时。
相关代码
模型定义
Market 模型
public class Market { [Key] public int Id { get; set; } public string Name { get; set; } public ICollection<PredefinedElement> PredefinedElements { get; set; } = new List<PredefinedElement>(); }
PredefinedElement 模型
public class PredefinedElement { [Key] public int Id { get; set; } public string Name { get; set; } // 多对多关联 public ICollection<Market> Markets { get; set; } = new List<Market>(); public ICollection<Product> Products { get; set; } = new List<Product>(); public ICollection<ActuationType> ActuationTypes { get; set; } = new List<ActuationType>(); }
Product 模型
public class Product { [Key] public int Id { get; set; } public string Name { get; set; } public ICollection<PredefinedElement> PredefinedElements { get; set; } = new List<PredefinedElement>(); }
ActuationType 模型
public class ActuationType { [Key] public int Id { get; set; } public string Name { get; set; } public ICollection<PredefinedElement> PredefinedElements { get; set; } = new List<PredefinedElement>(); }
前端Radzen Blazor提交逻辑
Submit 提交方法
async Task Submit() { var predefinedElement = new PredefinedElement { Id = editModel.Id, Name = editModel.Name, Markets = selectedMarkets.ToList(), Products = selectedProducts.ToList(), ActuationTypes = selectedActuationTypes.ToList() }; if (isEditMode) { await _predefinedElementService.UpdatePredefinedElement(predefinedElement); } else { await _predefinedElementService.CreatePredefinedElement(predefinedElement); } DialogService.Close(true); }
关联项选择事件
void OnMarketSelected(IEnumerable<Market> selected) { selectedMarkets = selected; } void OnProductSelected(IEnumerable<Product> selected) { selectedProducts = selected; } void OnActuationTypeSelected(IEnumerable<ActuationType> selected) { selectedActuationTypes = selected; }
服务层HTTP请求代码
public class PredefinedElementService { private readonly HttpClient _httpClient; public PredefinedElementService(HttpClient httpClient) { _httpClient = httpClient; } public async Task CreatePredefinedElement(PredefinedElement model) { var response = await _httpClient.PostAsJsonAsync("api/PredefinedElements", model); response.EnsureSuccessStatusCode(); } public async Task UpdatePredefinedElement(PredefinedElement model) { var response = await _httpClient.PutAsJsonAsync($"api/PredefinedElements/{model.Id}", model); response.EnsureSuccessStatusCode(); } }
API控制器代码
[Route("api/[controller]")] [ApiController] public class PredefinedElementsController : ControllerBase { private readonly AppDbContext _dbContext; public PredefinedElementsController(AppDbContext dbContext) { _dbContext = dbContext; } [HttpPost] public async Task<IActionResult> Create([FromBody] PredefinedElement model) { if (!ModelState.IsValid) { return BadRequest(ModelState); } _dbContext.PredefinedElements.Add(model); await _dbContext.SaveChangesAsync(); // 异常触发点 return CreatedAtAction(nameof(GetById), new { id = model.Id }, model); } [HttpPut("{id}")] public async Task<IActionResult> Update(int id, [FromBody] PredefinedElement model) { if (id != model.Id) { return BadRequest(); } _dbContext.Entry(model).State = EntityState.Modified; try { await _dbContext.SaveChangesAsync(); // 异常触发点 } catch (DbUpdateConcurrencyException) { if (!PredefinedElementExists(id)) { return NotFound(); } else { throw; } } return NoContent(); } private bool PredefinedElementExists(int id) { return _dbContext.PredefinedElements.Any(e => e.Id == id); } }
已尝试的排查动作
- 为所有实体主键添加
[Key]特性,确认主键配置无误 - 检查数据库关联表结构,外键约束均正常
- 项目由两个项目合并而来,存在另一个关联的数据库上下文,暂未排查上下文冲突
求问如何解决这个多对多关联重复实体时触发的ArgumentNullException问题?
内容的提问来源于stack exchange,提问作者j_mzt
相关产品推荐
相关产品推荐

