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

.NET Web API C#:如何通过GET方法仅选择模型部分属性?

问题

需要实现一个GET接口,仅返回User模型的指定属性及关联模型的部分字段:

  • 需返回的User属性:IdUser、UserName、UserMail、UserCompany
  • 需返回的关联属性:Profession的IdProfession、ProfessionName;ProfessionField的IdProfessionField、ProfessionFieldName
  • 排除字段:UserProfessionId、UserProfessionFieldId、UserPicture、DataUsages及关联模型的冗余字段

相关模型代码

User模型

namespace Sims.Models
{
    public partial class User
    {
        public User()
        {
            DataUsages = new HashSet<DataUsage>();
        }

        public long IdUser { get; set; }
        public int UserProfessionId { get; set; }
        public int UserProfessionFieldId { get; set; }
        public string? UserName { get; set; }
        public string? UserMail { get; set; }
        public string? UserCompany { get; set; }
        public byte[]? UserPicture { get; set; }
        public virtual Profession UserProfession { get; set; } = null!;
        public virtual ProfessionField UserProfessionField { get; set; } = null!;
        public virtual ICollection<DataUsage> DataUsages { get; set; }
    }
}

Profession模型

namespace Sims.Models
{
    public partial class Profession
    {
        public Profession()
        {
            ProfessionFields = new HashSet<ProfessionField>();
            Users = new HashSet<User>();
        }

        public int IdProfession { get; set; }
        public string ProfessionName { get; set; } = null!;
        public virtual ICollection<ProfessionField> ProfessionFields { get; set; }
        public virtual ICollection<User> Users { get; set; }
    }
}

当前实现及问题

当前GET方法代码:

// GET: api/Users
[HttpGet]
public async Task<ActionResult<IEnumerable<User>>> GetUsers()
{
    return await _context.Users
        //.Include(u => u.UserProfession)
          .Select(u => new User {
                 IdUser = u.IdUser,
                 UserName =u.UserName,
                 UserMail = u.UserMail,
                 UserCompany = u.UserCompany,
                 UserProfessionField = u.UserProfessionField
             }).ToListAsync();
}

返回结果包含大量不需要的字段(如UserProfessionId、DataUsages等),不符合需求。


解决方案

1. 创建DTO(数据传输对象)

定义一个专门用于返回数据的DTO类,只包含需要的字段:

public class UserDto
{
    public long IdUser { get; set; }
    public string? UserName { get; set; }
    public string? UserMail { get; set; }
    public string? UserCompany { get; set; }
    
    // 关联Profession的字段
    public int ProfessionId { get; set; }
    public string ProfessionName { get; set; } = null!;
    
    // 关联ProfessionField的字段
    public int ProfessionFieldId { get; set; }
    public string ProfessionFieldName { get; set; } = null!;
}

2. 修改GET方法

使用Select投影到DTO,同时确保Include关联模型(避免懒加载导致额外查询):

// GET: api/Users
[HttpGet]
public async Task<ActionResult<IEnumerable<UserDto>>> GetUsers()
{
    return await _context.Users
        .Include(u => u.UserProfession)
        .Include(u => u.UserProfessionField)
        .Select(u => new UserDto
        {
            IdUser = u.IdUser,
            UserName = u.UserName,
            UserMail = u.UserMail,
            UserCompany = u.UserCompany,
            // 映射Profession字段
            ProfessionId = u.UserProfession.IdProfession,
            ProfessionName = u.UserProfession.ProfessionName,
            // 映射ProfessionField字段
            ProfessionFieldId = u.UserProfessionField.IdProfessionField,
            ProfessionFieldName = u.UserProfessionField.ProfessionFieldName
        })
        .ToListAsync();
}

关键说明

  • 不要直接实例化User类返回:原模型包含大量不需要的字段,即使只赋值部分属性,序列化时仍会输出所有公共属性(未赋值的会显示默认值或null)。
  • 必须Include关联模型:如果不使用Include,EF Core会通过懒加载加载关联数据,导致额外的数据库查询,影响性能;使用Include可以一次性加载所需关联数据。
  • 投影到DTO是最佳实践:DTO可以精准控制返回字段,避免暴露敏感数据或冗余信息,同时让API返回结构更清晰。

优化后的返回示例

[
  {
    "idUser": 1,
    "userName": "user_test",
    "userMail": "mail@test.com",
    "userCompany": "TestCompany",
    "professionId": 1,
    "professionName": "运动员",
    "professionFieldId": 1,
    "professionFieldName": "Sports"
  },
  {
    "idUser": 2,
    "userName": "roger_federer",
    "userMail": null,
    "userCompany": null,
    "professionId": 1,
    "professionName": "运动员",
    "professionFieldId": 1,
    "professionFieldName": "Sports"
  }
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 07:31:20