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

如何使用EF Core调用PostgreSQL函数并获取返回结果

你遇到的报错是因为FromSqlRaw 并非DatabaseFacade类型(也就是_context.Database的所属类型)的扩展方法,它仅可用于DbSet<T>或无键实体的查询集合,直接在Database属性上调用自然找不到对应方法。

EF Core完全支持调用数据库函数执行原生SQL返回多行结果的场景,你可以根据需求选择以下两种解决方案:

方案1:使用无键实体+动态Set调用(全版本EF Core支持)

这种方案适合返回结构相对固定的场景,不需要你提前在DbContext中预定义DbSet属性,不会侵入现有上下文的映射配置:

  1. 先定义和函数返回列结构匹配的POCO类,添加[Keyless]特性标注为无键实体,避免EF要求配置主键:
[Keyless]
public class CityResult
{
    // 属性名、类型与city表的列一一对应即可
    public int Id { get; set; }
    public string CityName { get; set; }
    // 其他字段按需添加
}
  1. 调整你的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 03:06:02