ABP.Vnext使用postgis

1.关于ABP使用postgis配置流程。首先在Acme.BookStore.EntityFrameworkCore项目中安装Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite

2.安装好之后在Domain层创建一个使用地理几何的类。

 [Table("ChinaGis")]
 public class ChinaGis : Entity
 {
     [Column("Id")]
     public override string Id { get; protected set; }
    
     public string name { get; set; }
     public Geometry geom { get; set; }
 }

3.将实体添加到上下文,然后再程序包管理器使用迁移命令Add-Migration fss,此时会报错:The property 'gis_osm_railways_free_1.geom' is of type 'Geometry' which is not supported by the current database provider. Either change the property CLR type, or ignore the property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

造成这个错误的原因是没有启用PostGis扩展,在BookStoreDbContextFactory里面,启用一下就可以了。

var builder = new DbContextOptionsBuilder()
            .UseNpgsql(configuration.GetConnectionString("Default"),
            x=>x.UseNetTopologySuite());

BookStoreDbContextFactory这个主要是在使用命令行迁移的时候使用的,如果使用Acme.BookStore.DbMigrator进行生成,需要在BookStoreEntityFrameworkCoreModule里面启用一下UseNetTopologySuite

 Configure(options =>
 {
         /* The main point to change your DBMS.
          * See also BookStoreMigrationsDbContextFactory for EF Core tooling. */
     options.UseNpgsql(x=>x.UseNetTopologySuite());
     
 });

4.在上面配置都做完之后,在使用Add-Migration fss,构建成功之后,使用命令Update-Databse初始化数据库,也可以直接运行Acme.BookStore.DbMigrator程序来生成,都可以,成功之后就可以在数据库中看到ChinaGis 表了。

TIP:在运行Update-Databse如果报错,Npgsql.PostgresException (0x80004005): 42704: 类型 "geometry" 不存在,,报错原因,是因为数据库中没有启用postgis扩展,解决方法:在OnModelCreating方法里面增加builder.HasPostgresExtension("postgis");,启用postgis扩展。

5.在上述所有操作都完成之后,在Domain层ChinaGis下面运行abphelper generate crud ChinaGis -d path,执行成功之后,删除生成的多余项,先不用关注其他操作,只看Application层。在这里要注意一下,无论是添加还是查询,在自动生成的dao里面都不可以有Geometry类型的,否则,会报错,报如下错误,可能是接口返回的原因吧。查询的时候将Geometry更改为string类型,程序可以直接映射

 "message": "对不起,在处理你的请求期间,产生了一个服务器内部错误!",

 6.注意,在创建数据的时候,dto里面Geometry不能直接和和数据库里面直接映射,需要进行转换。

下面是添加和查询的代码。

 public async override Task CreateAsync(CreateUpdateChinaGisDto input)
 {
     await CheckCreatePolicyAsync().ConfigureAwait(continueOnCapturedContext: false);
     ChinaGis entity = await MapToEntityAsync(input).ConfigureAwait(continueOnCapturedContext: false);
     TryToSetTenantId(entity);
     Coordinate[] points =
     {
             new Coordinate(124.3786722,40.1239114),
             new Coordinate(124.3782163,40.124215)
         };
     LineString[] lineString = { new LineString(points) };

     MultiLineString multiLineString = new MultiLineString(lineString);
     Geometry geometry = multiLineString;
     entity.geom = multiLineString;
     await Repository.InsertAsync(entity, autoSave: true).ConfigureAwait(continueOnCapturedContext: false);
     return await MapToGetOutputDtoAsync(entity).ConfigureAwait(continueOnCapturedContext: false);
 }
 public async override Task> GetListAsync(PagedAndSortedResultRequestDto input)
 {
     try
     {
         await CheckGetListPolicyAsync();
         var query = await CreateFilteredQueryAsync(input);
         var totalCount = await AsyncExecuter.CountAsync(query);
         query = ApplySorting(query, input);
         query = ApplyPaging(query, input);
         var entities = await AsyncExecuter.ToListAsync(query);
         var entityDtos = await MapToGetListOutputDtosAsync(entities);
         return new PagedResultDto(
             totalCount,
             entityDtos
         );

     }
     catch (Exception ex)
     {
         throw ex;
     }
   
 }

7.关于使用ef操作postgis,我更建议直接使用sql的方式,这种方式更简单便捷一些,在abphelper生成的数据上下文中,添加sql语句

 public class ChinaGisRepository : EfCoreRepository, IChinaGisRepository
 {
     public ChinaGisRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider)
     {
     }
     public async Task> GetFdd()
     {
         string sql = "select  *from public.ChinaGis";
         var dbContext = await GetDbContextAsync();

         return await dbContext.Set().FromSqlRaw(sql).ToListAsync();
     }
 }

你可能感兴趣的:(数据库,oracle)