You need to enable JavaScript to run this app. 如何在.NET EF Core开发的API中获取指定Diet对应的Recipe列表
优惠活动
大模型
产品
解决方案
定价
更多

如何在.NET EF Core开发的API中获取指定Diet对应的Recipe列表

问题根源

你遇到的两个核心错误原因如下:

  1. 路由配置缺失:你的Action标注了[FromRoute] int DietId但路由模板没有对应的{DietId}占位符,导致接口无法从路由中拿到传入的DietId,参数默认值为0,自然筛选不到对应的Diet,返回空列表。
  2. 类型转换非法:你通过Select创建的是匿名类型对象,既不是Diet实体也不是Recipe实体,强转不符合.NET类型系统规则,直接抛出类型转换异常。

解决方案

方案1:直接返回Recipe实体列表

如果允许直接返回Recipe实体,直接用SelectMany压平关联的Recipes集合即可:

[HttpGet("[action]/{DietId}")] // 补全路由占位符,才能正常读取路由中的DietId
public async Task<IEnumerable<Recipe>> GetRecipesFromDiet([FromRoute] int DietId)
{
    return await _context.Diets
        .Where(d => d.DietId == DietId)
        .SelectMany(d => d.Recipes) // 把每个Diet对应的Recipes集合压平为Recipe序列
        .AsNoTracking()
        .ToListAsync();
}

注:EF Core 3.0及以上版本的投影查询会自动处理关联加载,不需要手动加Include也能正常获取关联数据。

方案2:返回自定义DTO(仅返回需要的字段)

如果不需要返回Recipe实体的全部字段,建议先定义DTO类,再做投影:

  1. 首先定义Recipe传输对象:
public class RecipeDto
{
    public int RecipeId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string Preparation { get; set; }
    public string Ingredients { get; set; }
}
  1. 修改Action代码:
[HttpGet("[action]/{DietId}")]
public async Task<IEnumerable<RecipeDto>> GetRecipesFromDiet([FromRoute] int DietId)
{
    return await _context.Diets
        .Where(d => d.DietId == DietId)
        .SelectMany(d => d.Recipes.Select(r => new RecipeDto
        {
            RecipeId = r.RecipeId,
            Name = r.Name,
            Description = r.Description,
            Preparation = r.Preparation,
            Ingredients = r.Ingredients
        }))
        .AsNoTracking()
        .ToListAsync();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 03:45:04