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

.NET 5获取用户收藏书籍列表返回空集合问题求助

问题:EF Core查询用户收藏书籍返回空列表(用户实际有数据)

基于.NET 5 + Entity Framework采用仓储模式开发接口,需求是从User实体的Book类型列表提取数据,转换为BookDto列表返回。Postman调用接口返回200 OK,但得到空列表[],已确认用户的LikedBooks列表在数据库中存在数据,调试时user对象不为空且数据正确,求解决思路。

提供的代码

[HttpGet("GetUserFavorites")]
public async Task<ActionResult<List<BookDto>>> GetUserLikedBooks()
{
    var username = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;

    return await _likeRepository.GetUserFavoriteBooks(username);
}

public async Task<List<BookDto>> GetUserFavoriteBooks(string username)
{
    var user = await _userRepo.GetUserByUsername(username);

    if (user == null)
    {
        throw new ArgumentException("Something gone wrong, try again.");
    }

    user.LikedBooks ??= new List<Book>();
        
    var bookDtos = user.LikedBooks.Select(x => new BookDto
            {
                Title = x.Title,
                Author = x.Author,
                PublicationYear = x.PublicationYear,
                Description = x.Description,
                Count = x.Count
            })
            .ToList();

    await _context.SaveChangesAsync();

    return bookDtos;
}

public class User
{
    public int Id { get; set; }
    public string UserName { get; set; }
    public List<Book> LikedBooks { get; set; }
}

public class Book
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Author { get; set; }
    public int PublicationYear { get; set; }
    public string Description { get; set; }
    public int Count { get; set; }
}

public class BookDto
{
    public string Title { get; set; }
    public string Author { get; set; }
    public int PublicationYear { get; set; }
    public string Description { get; set; }
    public int Count { get; set; }
}

解决建议

1. 确保仓储方法加载了关联集合

EF Core默认不会自动加载导航属性,若GetUserByUsername仅查询User的基础字段,未包含LikedBooks,则即使数据库有数据,user.LikedBooks也会是空集合或null。修改仓储方法,使用Include显式加载关联数据:

public async Task<User> GetUserByUsername(string username)
{
    return await _context.Users
        .Include(u => u.LikedBooks) // 加载关联的LikedBooks集合
        .FirstOrDefaultAsync(u => u.UserName == username);
}

2. 移除无意义的SaveChangesAsync调用

当前代码中await _context.SaveChangesAsync();属于冗余操作,因为仅做查询和DTO转换,未修改任何数据,直接删除即可避免不必要的数据库交互。

3. 验证Claim获取的用户名准确性

确认User.FindFirst(ClaimTypes.NameIdentifier)获取的内容是否为正确的用户名。部分认证配置中NameIdentifier存储的是用户ID而非用户名,可尝试改用ClaimTypes.Name获取:

var username = User.FindFirst(ClaimTypes.Name)?.Value;

同时检查认证配置,确保NameIdentifier的取值与User.UserName匹配。

4. 检查实体关系配置

确认User与Book的关系在DbContext中正确配置,例如:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<User>()
        .HasMany(u => u.LikedBooks)
        .WithOne() // 若Book无反向导航属性则使用此配置
        .OnDelete(DeleteBehavior.Cascade); // 根据业务需求设置删除行为
}

修改后的示例代码

public async Task<List<BookDto>> GetUserFavoriteBooks(string username)
{
    var user = await _userRepo.GetUserByUsername(username);

    if (user == null)
    {
        throw new ArgumentException("用户不存在,请重试。");
    }

    user.LikedBooks ??= new List<Book>();
        
    var bookDtos = user.LikedBooks.Select(x => new BookDto
            {
                Title = x.Title,
                Author = x.Author,
                PublicationYear = x.PublicationYear,
                Description = x.Description,
                Count = x.Count
            })
            .ToList();

    return bookDtos;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 08:15:33