EF Core调用存储过程时如何获取额外的Managing Level列
解决EF Core调用存储过程获取实体外字段的问题
以下是几种可行的方案,根据实际场景选择:
1. 创建专用DTO类(推荐)
定义一个包含Employee所有字段和ManagingLevel的DTO,专门用于接收存储过程的返回结果,这是最规范的做法,不会污染原有实体。
// 定义DTO类 public class EmployeeWithManagerLevel { // 复制Employee实体的所有属性 public int Id { get; set; } public string Name { get; set; } public string Department { get; set; } // 新增存储过程返回的ManagingLevel字段 public int ManagingLevel { get; set; } } // 在DbContext中注册这个DTO(EF Core 3.0+也可以不用注册直接用SqlQuery) public DbSet<EmployeeWithManagerLevel> EmployeeWithManagerLevels { get; set; } // 调用存储过程 var employeeId = 123; var result = dbContext.EmployeeWithManagerLevels .FromSqlRaw("EXEC EmployeeManagers @EmployeeId = {0}", employeeId) .ToList();
2. 给原有实体添加非映射属性
如果只是临时需求,可以在Employee实体上添加[NotMapped]标记的属性,这样EF Core不会将其映射到数据库列,但会接收存储过程返回的对应字段值。
public class Employee { public int Id { get; set; } public string Name { get; set; } public string Department { get; set; } // 添加非映射属性,用于接收存储过程的ManagingLevel [NotMapped] public int ManagingLevel { get; set; } } // 调用存储过程 var employeeId = 123; var employees = dbContext.Employees .FromSqlRaw("EXEC EmployeeManagers @EmployeeId = {0}", employeeId) .ToList(); // 此时employees中的每个对象都已填充ManagingLevel值
3. 使用匿名类型或动态类型(EF Core 5.0+)
如果不需要复用结果类型,可以直接用SqlQuery查询到动态对象,再投影成匿名类型,省去定义额外类的步骤。
var employeeId = 123; var result = dbContext.Database.SqlQuery<dynamic>( "EXEC EmployeeManagers @EmployeeId = {0}", employeeId) .Select(x => new { Id = x.Id, Name = x.Name, ManagingLevel = x.ManagingLevel }) .ToList();
方案对比
- DTO类:最符合SOLID原则,适合长期使用,避免实体污染
- 非映射属性:快速实现临时需求,但会增加实体的冗余属性
- 匿名/动态类型:适合一次性查询,无需额外定义类,但无法复用类型
内容的提问来源于stack exchange,提问作者Макс
相关产品推荐
相关产品推荐

