gpt4 book ai didi

postgresql - 使用 F# 中的 Npgsql 的用户定义的 postgresql 类型

转载 作者:行者123 更新时间:2023-11-29 13:19:23 25 4
gpt4 key购买 nike

我们最大限度地使用postgresql的特性来减轻我们的开发工作。我们在 postgresql 中大量使用自定义类型(用户定义的类型);我们的大多数函数和存储过程要么将它们作为输入参数,要么返回它们。

我们想在 F# 的 SqlDataProvider 中使用它们。这意味着我们应该能够以某种方式告诉 F# 如何将 F# 用户类型映射到 postgresql 用户类型。也就是说

  1. Postgresql 有我们定义的用户类型 post_user_defined
  2. F# 有我们定义的用户类型 fsharp_user_defined

我们应该指示 Npgsql 以某种方式执行此映射。到目前为止,我的研究为我指出了两种方法,但我对它们都不是很清楚。感谢任何帮助

方法一

NpgsqlTypes 命名空间有一组预定义的 postgresql 类型映射到开箱即用的 .NET。其中很少是类,其他是结构。假设我想使用 postgresql 的内置类型点,它由 Npgsql 通过 NpgsqlPoint 映射到 .NET。我可以像这样将其映射到特定于应用程序的数据结构:

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

(来自 PostgreSQLTests.fsx)

在这种情况下,已经定义了 postgresql point 和 NpgsqlPoint (.NET)。现在我想为我的自定义类型做同样的事情。

假设用户定义的 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,它们没有公开的构造函数。

我在这里走投无路了!

方法二

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()let prd = new PgProductType("F#Product","") 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'.

奇怪的是错误报告:constructor 'Invoke' takes 0 argument(s) but is here given 1。 F# 方面对 postgresql 函数采用的参数完全视而不见。它确实认识到函数 FuncIproduct 存在,但对它采用的参数视而不见。

最佳答案

关于您的第一种方法,正如您所了解的那样,NpgsqlTypes 包含一些 Npgsql 开箱即用支持的类型 - 但这些只是 PostgreSQL 内置类型。如果不更改 Npgsql 的源代码,您就无法向其中添加新类型,这不是您想要做的事情。

此外,您还应该了解用户定义类型(PostgreSQL 称之为“复合”)和完全独立的类型(例如 point)之间的区别。后者是完整类型(类似于 int4),具有自己的自定义二进制表示,而前者则不是。

您的第二种方法是正确的——Npgsql 完全支持 PostgreSQL 复合类型。我不知道 SqlDataProvider 是如何工作的——我假设这是一个特定于 F# 的类型提供程序——但是一旦你通过 MapCompositeGlobally 正确映射了你的复合 Material ,Npgsql 允许你通过将 NpgsqlParameter 的值设置为 PgProductType 的实例来透明地编写它.首先尝试让它与类型提供程序一起工作可能是值得的。

关于postgresql - 使用 F# 中的 Npgsql 的用户定义的 postgresql 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44446588/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com