Entity Framework DB First存储过程函数导入映射问题排查
EDMX存储过程返回类型显示为「无」但代码存在类型定义的原因
这是Entity Framework DB First模式下针对多结果集存储过程的设计器原生限制:
- 只要存储过程包含多段顺序执行的SELECT语句,模型同步向导就会自动将对应Function Import的返回类型在可视化界面标记为「无」,但不会删除EDMX源码中已存在的自定义映射配置,因此自动生成的上下文代码中依然会保留
ObjectResult<EMPLOYEEDATA>的返回定义。 - 你在XML源码中看到的
EMPLOYEEDATA映射不属于可视化设计器的支持配置范围,所以在模型浏览器中找不到对应的配置入口。
EMPLOYEEDATA映射的实际存储位置
右键EDMX文件选择「打开方式 > XML(文本)编辑器」,可以在两个节点段找到对应配置:
- 概念模型段:位于
<edmx:ConceptualModels>下的Schema节点内,既存储了EMPLOYEEDATA作为复杂类型/实体类型的完整结构定义,也存储了FunctionImport的返回值声明——只要这里的FunctionImport节点保留了ReturnType属性,自动生成的上下文代码就会输出对应泛型返回值,和可视化界面的显示无关。 - 映射规则段:位于
<edmx:Mappings>下的Mapping节点内,存储了存储过程返回列到EMPLOYEEDATA类型属性的绑定关系,是EF执行查询时做字段映射的实际依据。
为存储过程新增多返回结果映射的方法
EF设计器本身不支持多结果集存储过程的可视化配置,需要手动修改EDMX源码配合分部类代码实现,操作步骤如下:
- 在概念模型段的Schema节点下,按存储过程中SELECT语句的返回列结构,新增后续需要映射的复杂类型定义,保证字段的数据类型、顺序和数据库返回完全一致。
- 找到对应存储过程的
FunctionImport节点,删除原有单个ReturnType属性,按SELECT语句的执行顺序,新增多个ReturnType子节点分别绑定你定义好的所有返回类型。 - 在映射规则段找到对应存储过程的
FunctionImportMapping节点,按返回顺序新增多个ResultMapping子节点,分别配置每个返回类型的属性和数据库返回列的对应关系。 - 不要直接修改自动生成的
modelContext.cs文件(后续更新模型会被覆盖),新建一个上下文类的分部类文件,编写多结果集读取逻辑,参考实现代码:
public partial class YourDbContext { public Tuple<List<EMPLOYEEDATA>, List<YOUR_SECOND_TYPE>> GetDataMultiResult(int? isActive) { var isActiveParam = new SqlParameter("@IsActive", isActive ?? (object)DBNull.Value); using (var reader = Database.ExecuteReader(CommandType.StoredProcedure, "GetData", isActiveParam)) { var objectContext = ((IObjectContextAdapter)this).ObjectContext; // 读取第一个结果集 var firstResult = objectContext.Translate<EMPLOYEEDATA>(reader).ToList(); // 移动到下一个结果集读取 reader.NextResult(); var secondResult = objectContext.Translate<YOUR_SECOND_TYPE>(reader).ToList(); // 有更多结果集重复调用NextResult加Translate即可 return Tuple.Create(firstResult, secondResult); } } }
注意:每次通过模型向导从数据库更新EDMX时,设计器会自动重置FunctionImport节点的返回类型配置,你需要重新补全多返回类型的XML声明,多结果集的读取逻辑放在分部类中不会被覆盖,可以正常保留。
内容的提问来源于stack exchange,提问作者AKS
相关产品推荐
相关产品推荐

