如何使用EF Core调用PostgreSQL函数并获取返回结果
你遇到的报错是因为FromSqlRaw 并非DatabaseFacade类型(也就是_context.Database的所属类型)的扩展方法,它仅可用于DbSet<T>或无键实体的查询集合,直接在Database属性上调用自然找不到对应方法。
EF Core完全支持调用数据库函数执行原生SQL返回多行结果的场景,你可以根据需求选择以下两种解决方案:
方案1:使用无键实体+动态Set调用(全版本EF Core支持)
这种方案适合返回结构相对固定的场景,不需要你提前在DbContext中预定义DbSet属性,不会侵入现有上下文的映射配置:
- 先定义和函数返回列结构匹配的POCO类,添加
[Keyless]特性标注为无键实体,避免EF要求配置主键:
[Keyless] public class CityResult { // 属性名、类型与city表的列一一对应即可 public int Id { get; set; } public string CityName { get; set; } // 其他字段按需添加 }
- 调整你的SQL语句:你原先写的
SELECT public.show()会返回单个复合类型的列,不会把行的字段展开,因此需要改为从函数返回的结果集中查询所有列,最终执行代码如下:
var listOfCities = _context.Set<CityResult>() .FromSqlRaw("SELECT * FROM public.show()") .ToList();
方案2:直接操作底层连接返回动态结果(适配任意返回类型)
如果你完全不想定义POCO类,需要适配任意返回结构的自定义查询,可以直接获取EF上下文底层的数据库连接,用原生ADO.NET读取动态结果:
using var connection = _context.Database.GetDbConnection(); await connection.OpenAsync(); using var command = connection.CreateCommand(); command.CommandText = "SELECT * FROM public.show()"; // 如果有参数可以通过command.Parameters添加,避免SQL注入 using var reader = await command.ExecuteReaderAsync(); var resultList = new List<dynamic>(); while (await reader.ReadAsync()) { var row = new System.Dynamic.ExpandoObject() as IDictionary<string, object>; for (int i = 0; i < reader.FieldCount; i++) { row[reader.GetName(i)] = reader.IsDBNull(i) ? null : reader.GetValue(i); } resultList.Add(row); }
内容的提问来源于stack exchange,提问作者EthernalHusky
相关产品推荐
相关产品推荐

