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

Blazor WASM添加带分类的赞美诗触发SqlException问题求助

问题解决思路

问题根源

当你将前端选中的Category实体直接赋值给Hymn.Categories时,EF上下文并未跟踪这些从前端获取的Category对象,会默认将它们判定为新实体并尝试插入到Categories表中。但CategoryId是自增标识列(IDENTITY),默认不允许显式插入值,因此触发报错。


解决方案

方案1:在服务端标记分类为已存在状态

修改HymnService的AddHymn方法,手动将关联的分类实体标记为Unchanged(已存在),让EF只创建赞美诗与分类的关联记录,而非插入新分类:

public async Task AddHymn(Hymn hymn)
{
    foreach (var category in hymn.Categories)
    {
        // 告诉EF:这个分类是已存在的,不要插入
        _context.Entry(category).State = EntityState.Unchanged;
    }
    _context.Hymns.Add(hymn);
    await _context.SaveChangesAsync();
}

方案2:仅传递分类ID,避免传递完整实体

  1. 前端收集选中的分类ID,而非直接操作Category对象:
<div class="form-group">
    <label>Categories:</label>
    @foreach (var category in Categories)
    {
        <div class="form-check">
            <input class="form-check-input" type="checkbox" 
                   id="@category.CategoryId" 
                   @bind="@category.IsSelected" />
            <label class="form-check-label" for="@category.CategoryId">
                @category.CategoryName
            </label>
        </div>
    }
</div>
  1. 在CreateHymn方法中,仅收集选中的分类ID,再从数据库获取对应实体(或创建仅含ID的对象):
async Task CreateHymn()
{
    loading = true;
    try
    {
        // 收集选中的分类ID列表
        var selectedIds = Categories.Where(c => c.IsSelected)
                                   .Select(c => c.CategoryId)
                                   .ToList();
        
        // 方式A:从数据库加载已存在的分类实体
        Hymn.Categories = await CategoryService.GetCategoriesByIds(selectedIds);
        
        // 方式B(更高效):创建仅含ID的对象,标记为已存在
        // Hymn.Categories = selectedIds.Select(id => new Category { CategoryId = id }).ToList();
        
        await HymnService.AddHymn(Hymn);
        // 后续导航、提示逻辑不变
    }
    catch (Exception ex)
    {
        AlertService.Error(ex.Message);
        loading = false;
        StateHasChanged();
    }
}

方案3:使用EF的Attach方法关联已存在实体

如果选择方案2的方式B(仅传ID),可以在AddHymn中用Attach方法将分类绑定到上下文:

public async Task AddHymn(Hymn hymn)
{
    foreach (var category in hymn.Categories)
    {
        // 将仅含ID的分类对象附加到上下文,EF会判定为已存在
        _context.Categories.Attach(category);
    }
    _context.Hymns.Add(hymn);
    await _context.SaveChangesAsync();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 14:30:36