使用EF Core和Npgsql查询含Geometry类型数据库时的转换错误
错误原因
异常Can't cast database type public.geometry to Byte[]说明EF Core未正确配置PostgreSQL空间类型(geometry)的映射支持,默认情况下Npgsql会将geometry列解析为byte数组,无法直接转换为NetTopologySuite的Geometry对象。
解决步骤
安装必要的NuGet包
确保项目已安装Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite扩展包,该包提供EF Core与PostgreSQL空间类型的映射支持:Install-Package Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite # 或使用.NET CLI dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite配置DbContext启用NetTopologySuite支持
在DbContext的配置逻辑中添加UseNetTopologySuite()调用,让EF Core识别并处理空间类型:public class YourDbContext : DbContext { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { var connectionString = "你的数据库连接字符串"; optionsBuilder.UseNpgsql(connectionString, o => o.UseNetTopologySuite()); } public DbSet<Polyline> Polylines { get; set; } }验证实体类的Geometry类型
确保数据库对应的实体类(Polyline)中的Geometry属性类型与DTO一致,均为NetTopologySuite.Geometries.Geometry:public class Polyline { public Guid Id { get; set; } public string Layer { get; set; } // 其他属性... public Geometry? Geometry { get; set; } }检查AutoMapper投影配置
若使用AutoMapper的ProjectToDto()进行投影,确保映射配置未错误转换Geometry类型。例如,映射Profile应直接匹配同名同类型属性:public class MappingProfile : Profile { public MappingProfile() { CreateMap<Polyline, PolylineDto>(); // 默认自动匹配Geometry属性 } }确认数据库Geometry列的SRID一致性
确保数据库中geometry列的SRID(空间参考标识符)与代码使用的一致(默认通常为4326)。若不一致,可通过注解指定:[Column(TypeName = "geometry(Polygon, 4326)")] public Geometry? Geometry { get; set; }
验证
完成上述配置后重新运行查询,EF Core会自动将PostgreSQL的geometry列转换为NetTopologySuite的Geometry对象,类型转换异常将被解决。
内容的提问来源于stack exchange,提问作者badotnetdev

