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

.NET 6 Web API问题:访问product.Category.Name时Category为Null

问题排查与解决方案

核心原因分析

  1. EF Core关联数据未加载:仓储层仅返回Products的IQueryable,未主动加载关联的Category。EF Core默认延迟加载,但如果上下文在序列化时已释放,或延迟加载未开启,就会导致Category为null。
  2. DTO映射缺失:当前ProductDto未包含Category相关字段,即便EF加载了Category,AutoMapper也不会自动将这部分数据映射到DTO中。

解决方案步骤

步骤1:确保关联数据被加载

有两种方式可以加载关联的Category:

方式一:使用Include主动加载(推荐,按需加载场景)

修改仓储层的GetProducts方法,显式关联加载Category:

public IQueryable<Product> GetProducts()
{
    return _context.Products
        .Include(p => p.Category) // 加载关联的Category实体
        .OrderBy(x => x.Name);
}

方式二:开启延迟加载(全局需要关联数据的场景)

如果需要全局启用延迟加载,需满足两个条件:

  • 实体的导航属性已标记为virtual(你的代码已满足)
  • 在DbContext配置中开启延迟加载代理:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        .UseSqlServer("你的数据库连接字符串")
        .UseLazyLoadingProxies(); // 启用延迟加载
}

注意:延迟加载要求上下文在序列化时保持活跃,否则仍会出现null,比如控制器直接返回IQueryable时,序列化可能在上下文释放后执行。


步骤2:更新DTO并配置AutoMapper映射

先修改ProductDto,添加Category相关字段:

public class ProductDto
{
    public int Id { get; set; }
    public string Name { get; set; } = null!;
    public string Description { get; set; } = null!;
    public int CategoryId { get; set; }
    public double Price { get; set; }
    public string PhotoUrl { get; set; } = null!;
    // 添加CategoryDto字段
    public CategoryDto Category { get; set; } = null!;
}

然后配置AutoMapper的映射规则,确保实体到DTO的关联映射生效:

public class MappingProfile : Profile
{
    public MappingProfile()
    {
        CreateMap<Category, CategoryDto>();
        CreateMap<Product, ProductDto>();
    }
}

步骤3:修改控制器,返回DTO而非实体

直接返回实体IQueryable容易引发序列化问题,建议映射为DTO后返回:

[HttpGet]
public ActionResult<IEnumerable<ProductDto>> GetProducts()
{
    var products = _productRepository.GetProducts();
    if (!products.Any())
    {
        return NotFound();
    }
    var productDtos = _mapper.Map<IEnumerable<ProductDto>>(products);
    return Ok(productDtos);
}

额外检查:SeedData需包含Category数据

你的SeedData仅添加了Product,需确保Category也被正确初始化:

modelBuilder.Entity<Category>(entity =>
{
    entity.HasData(
        new Category { Id = 1, Name = "分类1" },
        new Category { Id = 2, Name = "分类2" }
    );
});

modelBuilder.Entity<Product>(entity =>
{
    entity.HasData(
        new Product { Id = 1, Name = "Hello", Description = "1", PhotoUrl = "111", Price = 10, CategoryId = 1 },
        new Product { Id = 2, Name = "World", Description = "2", PhotoUrl = "111", Price = 20, CategoryId = 2 }
    );
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 17:24:48