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語句中必須要寫一個相同別名對應實體名。

   新人發文,還請各位大佬指正。

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM