.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
相关产品推荐
相关产品推荐

