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

使用C#和Npgsql加载含EARTH字段的PostgreSQL表至Dataset报错求助

解决Npgsql读取PostgreSQL EARTH类型时的二进制输出函数错误

这个错误是因为Npgsql默认没有为PostgreSQL的earth类型(来自earthdistance扩展)提供内置的二进制序列化器,当NpgsqlDataAdapter尝试用二进制模式读取该类型数据时就会抛出42883错误。下面提供几种可行的解决方案:

方案1:临时绕过——查询时转换为文本类型

最简单的快速解决方法是在SQL查询中将earth类型转换为Npgsql能识别的文本格式,使用earth类型自带的earth_to_text函数:

SELECT *, earth_to_text(your_earth_column) AS your_earth_column_text FROM postretable;

之后在C#代码中读取your_earth_column_text字段的字符串值,再自行解析成需要的坐标格式(比如经纬度)。

方案2:注册自定义类型映射(推荐)

通过Npgsql的类型映射系统,让它能正确序列化/反序列化earth类型。首先确保你已经安装了earthdistance扩展(如果没装的话执行CREATE EXTENSION IF NOT EXISTS earthdistance;)。

步骤1:定义.NET对应类型

创建一个对应earth类型的.NET类,用来存储经纬度信息:

public class EarthCoordinate
{
    public double Latitude { get; set; }
    public double Longitude { get; set; }

    // 从earth类型的文本表示解析
    public static EarthCoordinate FromEarthText(string earthText)
    {
        var trimmed = earthText.Trim('(', ')');
        var parts = trimmed.Split(',', StringSplitOptions.TrimEntries);
        return new EarthCoordinate
        {
            Latitude = double.Parse(parts[0]),
            Longitude = double.Parse(parts[1])
        };
    }

    // 转换为earth类型的文本格式
    public override string ToString()
    {
        return $"({Latitude}, {Longitude})";
    }
}

步骤2:注册类型映射

在应用初始化的地方(比如Program.cs或者数据库连接初始化代码中),注册earth类型与自定义.NET类的映射:

// 注册earth类型映射
NpgsqlConnection.GlobalTypeMapper.MapComposite<EarthCoordinate>("earth", new[]
{
    new NpgsqlCompositeMember("lat", typeof(double)),
    new NpgsqlCompositeMember("lon", typeof(double))
});

这样Npgsql就能自动将数据库中的earth类型数据转换为EarthCoordinate对象,反之亦然。之后你原来的DataAdapter.Fill代码就能正常工作了。

关于“提供二进制输出函数”的说明

虽然可以在PostgreSQL中为earth类型编写自定义的二进制输出函数,但这需要使用C语言编写扩展,过程比较复杂且维护成本高,远不如客户端类型映射来得灵活。除非你有特殊的性能需求,否则不推荐这种方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:48:01