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

如何在.NET C#与SQL Server Management Studio中保存关联评论列表数据

解决方案:EF Core 一对多关系配置与数据存取

你的核心问题是未正确配置一对多实体关系,以及查询时未显式加载关联数据。以下是具体修正步骤:

1. 完善实体类的关系配置

补充User类的导航属性

你未贴出User类,需确保它包含评论集合的导航属性:

public class User
{
    public int Id { get; set; }
    // 其他属性...
    [JsonIgnore]
    public virtual List<Comment> Comments { get; set; } = new List<Comment>();
}

显式配置外键关系(可选但推荐)

在DbContext中用Fluent API明确关系,避免EF Core自动推断出错:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // Offer与Comment的一对多关系
    modelBuilder.Entity<Offer>()
        .HasMany(o => o.Comments)
        .WithOne() // 若需Comment反向导航到Offer,可改为c => c.Offer
        .HasForeignKey(c => c.OfferId)
        .OnDelete(DeleteBehavior.Cascade); // 删除Offer时自动删除关联评论,按需调整

    // User与Comment的一对多关系
    modelBuilder.Entity<User>()
        .HasMany(u => u.Comments)
        .WithOne() // 若需Comment反向导航到User,可改为c => c.User
        .HasForeignKey(c => c.UserId)
        .OnDelete(DeleteBehavior.Restrict); // 删除User时保留评论,按需调整
}

若需要Comment类包含反向导航到Offer和User,可修改Comment类:

public class Comment
{
    public int Id { get; set; }
    // 其他属性...
    public int UserId { get; set; }
    public int OfferId { get; set; }
    
    // 反向导航属性
    [JsonIgnore]
    public virtual User User { get; set; }
    [JsonIgnore]
    public virtual Offer Offer { get; set; }
}

2. 修正PostComment方法的冗余操作

你当前代码中,添加comment到existingOffer.Comments和existingUser.Comments后,再调用_context.Comments.Add(comment)属于重复操作——EF Core会通过导航属性自动追踪实体。简化后代码:

[HttpPost]
public async Task<ActionResult<Comment>> PostComment(Comment comment)
{
    var existingOffer = await _context.Offers.FindAsync(comment.OfferId);
    if (existingOffer == null)
    {
        return BadRequest("该Offer不存在");
    }

    var existingUser = await _context.Users.FindAsync(comment.UserId);
    if (existingUser == null)
    {
        return BadRequest("该用户不存在");
    }

    // 关联评论到Offer和User
    existingOffer.Comments.Add(comment);
    existingUser.Comments.Add(comment);
    
    await _context.SaveChangesAsync();

    return CreatedAtAction("GetComment", new { id = comment.Id }, comment);
}

3. 实现GET接口获取关联评论

要获取Offer或User的关联评论,需在查询时显式加载导航属性:

获取指定Offer的评论

[HttpGet("offers/{offerId}/comments")]
public async Task<ActionResult<List<Comment>>> GetOfferComments(int offerId)
{
    var comments = await _context.Comments
        .Where(c => c.OfferId == offerId)
        .ToListAsync();
    
    if (comments?.Count == 0)
    {
        return NotFound("该Offer暂无评论");
    }
    
    return comments;
}

获取指定User的评论

[HttpGet("users/{userId}/comments")]
public async Task<ActionResult<List<Comment>>> GetUserComments(int userId)
{
    var comments = await _context.Comments
        .Where(c => c.UserId == userId)
        .ToListAsync();
    
    if (comments?.Count == 0)
    {
        return NotFound("该用户暂无评论");
    }
    
    return comments;
}

获取Offer时同时返回评论(按需使用)

[HttpGet("offers/{id}")]
public async Task<ActionResult<Offer>> GetOffer(int id)
{
    var offer = await _context.Offers
        .Include(o => o.Comments) // 显式加载关联评论
        .FirstOrDefaultAsync(o => o.Id == id);
    
    if (offer == null)
    {
        return NotFound();
    }
    
    return offer;
}

4. 简化PostOffer方法

你当前PostOffer方法中的offer.Comments = new List<Comment>();属于冗余代码,因为Offer类的Comments属性已初始化新列表,可直接删除该行。


内容的提问来源于stack exchange,提问作者João Vieira

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 10:32:27