创建Item时意外生成新Category的技术问题求助
问题描述
我有一个包含Items和Categories两张表的数据库:
Item实体字段:Id、Name、Description、Quantity、Price、CategoryIdCategory实体字段:Id、Name
调用create接口创建Item时,系统会自动生成新的Category,并把新Category的Id赋值给Item的CategoryId,这不符合预期——我不需要创建新分类。
测试情况:Postman请求体传入"categoryId": 2,但返回体的categoryId变成了13;数据库里Items表该记录的categoryId是13,Categories表新增了一条Name为空的记录。
核心代码
Models > Item.cs
public class Item { public int Id { get; set; } public string Name { get; set; } = string.Empty; public string Description { get; set; } = string.Empty; public int Quantity { get; set; } public decimal Price { get; set; } [ForeignKey("CategoryId")] public int CategoryId { get; set; } public Category Category { get; set; } = new Category(); }
Dtos > Item > ItemDto.cs
public class ItemDto { public int Id { get; set; } public string Name { get; set; } = string.Empty; public string Description { get; set; } = string.Empty; public int Quantity { get; set; } public decimal Price { get; set; } public int CategoryId { get; set; } }
Dtos > Item > CreateItemDto.cs
public class CreateItemDto { public string Name { get; set; } = string.Empty; public string Description { get; set; } = string.Empty; public int Quantity { get; set; } public decimal Price { get; set; } public int CategoryId { get; set; } }
Repositories > ItemRepository.cs
public class ItemRepository : IItemRepository { private readonly ApplicationDBContext _context; public ItemRepository(ApplicationDBContext context) { _context = context; } public async Task<Item> CreateAsync(Item itemModel) { await _context.Items.AddAsync(itemModel); await _context.SaveChangesAsync(); return itemModel; } }
Controllers > ItemController.cs
[Route("api/item")] [ApiController] public class ItemController : ControllerBase { private readonly IItemRepository _itemRepo; public ItemController(IItemRepository itemRepo) { _itemRepo = itemRepo; } [HttpGet] [Route("get/{id}")] // 此方法将根据Id从数据库返回指定的Item public async Task<IActionResult> GetById([FromRoute] int id) { var item = await _itemRepo.GetByIdAsync(id); if(item == null) { return NotFound(); } return Ok(item.ToItemDto()); } [HttpPost] [Route("create")] public async Task<IActionResult> CreateAsync([FromBody] CreateItemDto itemDto) { if(!ModelState.IsValid) { return BadRequest(ModelState); } var itemModel = itemDto.ToItemFromCreate(); await _itemRepo.CreateAsync(itemModel); return CreatedAtAction(nameof(GetById), new { id = itemModel.Id }, itemModel.ToItemDto()); } }
解决方法
问题根源
Item类里的Category属性被初始化了new Category(),EF Core添加Item实体时,会自动追踪这个新创建的Category实例,将其当作新实体插入数据库,同时覆盖Item的CategoryId。
修复步骤
- 移除
Category属性的初始化
修改Item.cs,将Category属性的初始化代码删除:
public Category? Category { get; set; }
(可空类型用于避免非空警告,若使用.NET Framework,可直接写public Category Category { get; set; })
检查映射逻辑
确认ToItemFromCreate()扩展方法仅设置CategoryId,不初始化Category属性,避免额外创建分类实例。可选:校验分类存在性
如果需要确保传入的CategoryId对应数据库中已存在的分类,可在创建Item前添加校验:
// 在ItemController的CreateAsync方法中添加 using var context = new ApplicationDBContext(); var categoryExists = await context.Categories.AnyAsync(c => c.Id == itemDto.CategoryId); if (!categoryExists) { return BadRequest("指定的分类不存在"); }
需确保控制器已注入ApplicationDBContext,或在仓库层封装校验方法。
内容的提问来源于stack exchange,提问作者Bryan
相关产品推荐
相关产品推荐

