• EF框架操作postgresql,实现WKT类型坐标的插入,查询,以及判断是否相交


           1.组件配置

            首先,要下载.NET for Postgresql的驱动,npgsql,EF6,以及EntityFramework6.Npgsql,版本号 3.1.1.0.

            由于是mvc项目,所以,把相应的配置文件写在web.config里面,如下:

    1  <configSections>
    2     <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    3     <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    4   </configSections>

      由于项目数据的存储是用的MongoDB,此代码段必须添加在<configuration>标签下的第一个子节点,是对EF框架的引入声明.

    <!--EF框架与Npgsql整合-->
      <entityFramework>
        <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
          <parameters>
            <parameter value="v13.0" />
          </parameters>
        </defaultConnectionFactory>
        <providers>
          <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
          <provider invariantName="Npgsql" type="Npgsql.NpgsqlServices, EntityFramework6.Npgsql" />
        </providers>
      </entityFramework>

      此段配置是EF框架与npgsql的整合。

    <system.data>    
      <!--注册npgSql组件-->
       <DbProviderFactories>
         <remove invariant="Npgsql" />
         <add name="Npgsql" invariant="Npgsql" description=".Net Framework Data Provider for Postgresql" type="Npgsql.NpgsqlFactory, Npgsql" />
          <add name="dotConnect for PostgreSQL" invariant="Devart.Data.PostgreSql" description="Devart dotConnect for PostgreSQL" type="Devart.Data.PostgreSql.PgSqlProviderFactory, Devart.Data.PostgreSql, Version= 7.7.804.0, Culture=neutral, PublicKeyToken=09af7300eec23701"/>
        </DbProviderFactories> 
      </system.data>

      此段配置,是对npgsql组件的注册,缺失的话会报npgsql未注册的异常。

      用nuget直接下载上述组件,这些都应该会自动生成配置文件,我之前是因为写了一个控制台程序进行尝试,mvc项目里的组件

    都是直接引用的控制台程序里面的。

     <!--Postgresql数据库的字符串连接信息-->
      <connectionStrings>
        <add name ="db" connectionString ="Server=localhost;Port=5432;Database=db;User Id=postgres;Password=123456;" providerName="Npgsql"/>
      </connectionStrings>

        连接信息需要自己添加,不会生成。

     2.  数据库连接

       这里遇到了一个问题,明明配置文件中密码写的没问题,读到后台代码中时,ConnectString里总是没有密码,于是乎用笨方法,在c#代码里面自己在重写一遍ConnectString

      public class dbFactory : DbContext
     2     {
     3         public dbFactory(string databaseName, bool isDoInitialize = false)
     4             : base(databaseName)
     5         {
     6             if (!isDoInitialize)
     7             {
     8                 Database.Connection.Open();
     9                 Database.Connection.ConnectionString = "Server=127.0.0.1;Port=5432;Database=db;User Id=postgres;Password=123456";
    10 
    11                 Database.SetInitializer<dbFactory>(null);
    12 
    13 
    14 
    15             }
    16         }
    17 
    18 
    19 
    20 
    21 
    22         //public DbSet<Destination> Destination { set; get; }
    23         public DbSet<PuKouMap> PuKouMap
    24         {
    25             set;
    26             get;
    27 
    28         }
    29         public DbSet<Judyment> Judyment { set; get; }
    30     }

      而且必须要自己手动打开连接,否则初始化后连接状态一直是Closed,不知道有什么更好的方法。

     1 [Table("PuKouMapDb", Schema = "public")]
     2    public class PuKouMap
     3     {
     4         [Key]
     5         public int Id { set; get; }
     6         public int Type { set; get; }
     7         public string ObjectId { set; get; }
     8         public string Polygon { set; get; }
     9         public string ZipName { set; get; }
    10         public string FilePath { set; get; }
    11         public string FileNames { set; get; }
    12         public string ObjectName { set; get; }
    13     }

      要在实体类上面加一个注解,实体类对应表名写上,因为在sqlsever默认的架构师dbo,postgresql却是public,所以在这要改一下。

     1 public class BaseDao
     2     {
     3         public static dbFactory db = null;
     4        /// <summary>
     5        /// 派生类实例化时加载基类构造函数,进行数据库连接
     6        /// </summary>
     7         static BaseDao()
     8         {
     9             db = new dbFactory("db");
    10 
    11         }
    12         #region 得到建立连接后的数据操作接口
    13         public  dbFactory getDb() {
    14 
    15          
    16            return db;
    17         }
    18         #endregion
    19     }

     1  public class QueryString
     2     {
     3      
     4         public static  string Insert(PuKouMap p) {
     5          String  InsertAction = "INSERT INTO public.'PuKouMapDb' VALUES("+p.Type+","+p.ObjectId+","+"st_GeomFromText(" +"'"+ p.Polygon  +"'"+",4326)"+","+p.ZipName+","+p.FilePath+","+p.FileNames+","+p.ObjectName+";)";
     6             return InsertAction;
     7         }
     8         #region 断句加空格
     9         public static string GetPoKouMapByObjectIdString(String ObjectId) {
    10 
    11             String CheckAction = "SELECT a."Id",a."Type",a."ObjectId",ST_ASTEXT(a."Polygon") AS "Polygon",a."ZipName",a."FilePath",a."FileNames",a."ObjectName" "
    12             +"from public."PuKouMapDb" as a "+
    13               "where "
    14              +"a."ObjectId"='"+ObjectId+"'";
    15 
    16             return CheckAction;
    17         }
    18         #endregion
    19         public static string IsIntersects(String PolygonNew,String Geometry) {
    20 
    21             string IsIntersectsAction =  "SELECT ST_Intersects(st_GeomFromText(" + "'" + PolygonNew + "')" + "," +"'"+ Geometry +"'" +") AS "TrueOrFalse"";
    22             return IsIntersectsAction;
    23         }
    24 
    25         
    26         
    27         }

       postgresql的sql语句必须要注意的地方就是表名和字段名必须要加双引号,所以用了转义字符,插入直接用EF框架提供的Add(),方法就行了,会以坐标系缺省的情况插入进去.查询要用到ST_ASTEXT函数进行geometry类型向文本类型的转换,语句用EF框架的sqlQuery执行(感觉还不如用原生方法,做geomoetry分析,都必须用到postgis的空间分析函数,必须要写sql)

      判断是否相交则用ST_Intersects函数对两个geometry类型进行判断,返回值是一个bool类型,由于EF框架没有找到衔接postgresql的操作,返回值貌似只有对象,所以自己写了一个bool值实体类。

     public class Judyment
        {
            [Key]
           
            public bool TrueOrFalse { set; get; }
        }

      相当于是一个存放结果的容器。应当注意sql语句中必须要写一个相同别名对应实体名。

       新人发文,还请各位大佬指正。

      

  • 相关阅读:
    WINCE/WM5.0如何让安装完后自动运行程序
    Android 图片透明度处理代码
    windows mobile UI 自定义开始菜单图标
    Windows mobile 6捕获键盘操作
    HTTP的post和get总结
    提供一个Windows mobile Native UI 程序,循序渐进开发,并附有代码!
    Windows Mobile 中ComboBox【下拉列表】的使用
    注册表修改今日桌面左右软键的功能
    .net compact framework 注册表操作
    两种实现Toast 的例子(图片&文字)
  • 原文地址:https://www.cnblogs.com/amigod/p/postgres.html
Copyright © 2020-2023  润新知