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

ASP.NET Core中盒子嵌套书籍的数据库状态更新实现方案问询

优化方案与代码改进

你的初始实现思路是可行的,但可以从查询效率、代码简洁性和数据层与展示层分离这几个维度进行优化,以下是具体改进思路和代码示例:

核心优化点

  • 合并数据库查询,避免两次IO操作
  • 用字典缓存书籍数据,减少循环内的重复遍历
  • 使用ViewModel分离实体与展示数据,避免修改EF跟踪实体
  • 用LINQ简化插槽列表生成逻辑

改进后的代码实现

1. 定义展示用的ViewModel(推荐)

首先创建专门用于前端展示的ViewModel,避免直接操作EF实体:

public class BoxViewModel
{
    public string BoxId { get; set; }
    public string Color { get; set; }
    public List<BookSlotViewModel> BookSlots { get; set; }
}

public class BookSlotViewModel
{
    public short SlotNumber { get; set; }
    public bool IsExist { get; set; }
    public bool IsRead { get; set; }
}

2. 优化后的OnGet方法

public async Task OnGet(string color)
{
    // 一次查询获取指定颜色的盒子及其关联书籍,避免两次数据库访问
    var boxWithBooks = await db.BoxInfo
        .Include(b => b.BookInfo)
        .Where(b => b.Color == color)
        .ToListAsync();

    // 将书籍按BoxId分组存入字典,O(1)查找效率
    var bookDict = boxWithBooks
        .SelectMany(b => b.BookInfo)
        .GroupBy(b => b.BoxId)
        .ToDictionary(g => g.Key, g => g.ToDictionary(b => b.BookNumber, b => b.Status));

    // 转换为ViewModel集合
    BoxViewModels = boxWithBooks.Select(box => new BoxViewModel
    {
        BoxId = box.BoxId,
        Color = box.Color,
        // 用Enumerable.Range生成1-20的插槽,替代for循环
        BookSlots = Enumerable.Range(1, 20).Select(i => 
        {
            var slotNumber = (short)i;
            // 查找当前插槽的书籍状态
            bookDict.TryGetValue(box.BoxId, out var boxBooks);
            boxBooks?.TryGetValue(slotNumber, out var bookStatus);

            return new BookSlotViewModel
            {
                SlotNumber = slotNumber,
                IsExist = bookStatus != null && bookStatus != "Empty",
                IsRead = bookStatus == "Read"
            };
        }).ToList()
    }).ToList();
}

额外优化建议

  1. 数据库层面优化:给books表的BoxId和BookNumber字段建立联合索引,提升关联查询速度
  2. 前端展示优化:
    • 用CSS类标记不同状态的插槽,比如.read(绿色背景)、.unread(黄色背景)、.empty(灰色背景)
    • 表格布局可以用<table>嵌套,每个盒子作为一个子表格,匹配预期样式
  3. 避免EF实体修改:直接修改EF实体的BookList可能会触发不必要的变更跟踪,使用ViewModel能彻底避免这个问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 13:15:27