使用EF内存数据库时NpgsqlTsVector无法正常工作的问题
解决NpgsqlTsVector在EF Core内存数据库测试中的映射问题
针对你遇到的问题——真实PostgreSQL数据库中NpgsqlTsVector属性可正常使用,但内存数据库测试时因类型不支持报错,且全局忽略字段会影响真实环境,提供以下几种可行方案:
方案1:根据数据库提供程序动态配置
在DbContext的OnModelCreating方法中,判断当前使用的数据库类型,仅在内存数据库环境下忽略该字段,真实数据库环境保留映射:
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); if (Database.ProviderName == "Microsoft.EntityFrameworkCore.InMemory") { // 内存数据库下忽略Pesquisa字段 modelBuilder.Entity<Produto>().Ignore(p => p.Pesquisa); } else { // PostgreSQL环境下配置tsvector列类型 modelBuilder.Entity<Produto>() .Property(p => p.Pesquisa) .HasColumnType("tsvector"); } }
方案2:使用值转换器兼容内存数据库
通过值转换器将NpgsqlTsVector转换为内存数据库支持的string类型,这样测试环境可保留字段(但无法使用PostgreSQL全文搜索语法,需单独处理测试查询逻辑):
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); var tsVectorConverter = new ValueConverter<NpgsqlTsVector, string>( tsVector => tsVector.ToString(), str => NpgsqlTsVector.Parse(str)); modelBuilder.Entity<Produto>() .Property(p => p.Pesquisa) .HasConversion(tsVectorConverter) .HasColumnType("tsvector"); }
方案3:为测试环境创建专用DbContext
创建继承自原DbContext的测试专用上下文,在其中忽略Pesquisa字段,真实环境使用原上下文:
// 生产环境DbContext public class AppDbContext : DbContext { public DbSet<Produto> Produtos { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<Produto>() .Property(p => p.Pesquisa) .HasColumnType("tsvector"); } } // 测试专用DbContext public class TestAppDbContext : AppDbContext { protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<Produto>().Ignore(p => p.Pesquisa); } }
测试时使用TestAppDbContext初始化内存数据库,生产环境使用AppDbContext连接PostgreSQL。
内容的提问来源于stack exchange,提问作者AndreR
相关产品推荐
相关产品推荐

