2017-06-08 10 views
1

開発努力を容易にするためにpostgresqlの機能を最大限使用します。私たちは、postgresqlでカスタムタイプ(ユーザ定義タイプ)を大量に使用しています。ほとんどの関数とストアドプロシージャは、それらを入力パラメータとして使用するか、またはそれらを戻します。FからのNpgsqlを使用するユーザー定義のpostgresqlタイプ

F#のSqlDataProviderから使用したいと考えています。つまり、F#ユーザのタイプをpostgresqlのユーザタイプにマップする方法をF#に何とか伝えることができるはずです。言い換えれば

  1. PostgreSQLは、当社の定義されたユーザタイプがpost_user_definedた
  2. F#が私たちの定義されたユーザタイプは、我々は何とかこのマッピングを実行するためのNpgsqlを指示する必要があり

をfsharp_user_definedました。私の研究は、これまでのところ2つのアプローチを指摘しており、いずれも私には完全にはっきりしていません。任意の助けを理解され

アプローチ1

NpgsqlTypes名前空間は、ボックスの外に.NETにマッピングされたPostgreSQLのタイプの事前定義されたセットを有しています。それらのうちのいくつかはクラスであり、他のものは構造である。 NpgsqlPoint経由でNpgsqlによって.NETにマップされたpostgresqlの組み込み型ポイントを使用したいとします。既に定義されている。この場合、PostgreSQLの点とNpgsqlPoint(.NET)で

let point (x,y) = NpgsqlTypes.NpgsqlPoint(x,y) 

(PostgreSQLTests.fsxから)

:私はこのようなアプリケーション固有のデータ構造にこれをマッピングすることができます。今私は私のカスタムタイプのために同じことをしたいと思います。

は、ユーザー定義のPostgreSQLの複合体が

create type product_t as (name text, product_type text); 

であり、アプリケーションのデータ構造(F#が)レコード

type product_f = {name :string; ptype :string } 

やタプル

type product_f = string * string 

私はどのように伝えるかであると仮定します私の型をPostgreSQL関数/プロシージャのパラメータとして渡すときにNpgsqlを使用するには?パブリックなコンストラクタを持たないNpgsqTypes.NpgsqlDbType.CompositeまたはNpgsql.PostgresCompositeTypeを使用する必要があるようです。

私はここで死んでいます!

アプローチ2

this postからヒントを取って、私は、カスタムタイプを作成し、MapCompositeGloballyに登録するとPostgreSQL関数に渡すためにそれを使用することができます。だから、ここで私は、PostgreSQL側ではそれ

、タイプで私の手を試してみて、機能はそれぞれ

CREATE TYPE product_t AS 
    (name text, 
    product_type text) 

func_product(p product_t) RETURNS void AS 

そして、F#で自分のアプリケーションから

ある

type PgProductType(Name:string,ProductType:string)= 
    member this.Name = Name 
    member this.ProductType = ProductType 
    new() = PgProductType("","") 
Npgsql.NpgsqlConnection.MapCompositeGlobally<PgProductType>("product_t",null) 

、次に

タイププロバイダ= SqlDataProvider

レットCTX = Provider.GetDataContext()PRD =新しいPgProductTypeを聞かせて ( "F#の製品"、 "") ctx.Functions.FuncProduct.Invoke(PRD);;

ctx.Functions.FuncIproduct.Invoke(prd);; 
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 

stdin(29,1): error FS0501: The member or object constructor 'Invoke' takes 0 argument(s) but is here given 1. The requir 
ed signature is 'SqlDataProvider<...>.dataContext.Functions.FuncIproduct.Result.Invoke() : Unit'. 

誤りがあることを報告していることに注意すること。その奇妙な:コンストラクタの「起動」は0引数を取りますが、ここで1を与えています。 F#側のものは、postgresql関数がとる引数に対して完全に盲目的です。関数FuncIproductは存在するが、引数には盲目的であることを認識します。

答えて

1

NpgsqlTypesには、Npgsqlがサポートしているいくつかのタイプが含まれていますが、これらはPostgreSQLの組み込みタイプのみです。 Npgsqlのソースコードを変更することなく、新しいタイプを追加することはできません。これは実行したくないものです。

また、ユーザ定義タイプ(PostgreSQLが "複合"と呼ぶ)と完全に独立したタイプ(例えば、point)の違いを理解する必要があります。後者は完全な型(int4に似ています)で、独自のカスタムバイナリ表現を持ちますが、前者はそうではありません。

2番目のアプローチは適切です - NpgsqlはPostgreSQL複合型を完全にサポートしています。私はSqlDataProviderがどのように機能するか分かりません - これはF#固有の型プロバイダーであると仮定していますが、MapCompositeGlobally経由でコンポジットを適切にマップすると、NpgsqlはNpgsqlParameterの値をPgProductTypeのインスタンスに設定することによって、 。それはタイププロバイダーで最初に働かせることを試みる価値があるかもしれません。

関連する問題