postgresql - Postgresql 的 FSharp 数据类型提供程序

标签 postgresql f# npgsql type-providers f#-3.0

我正在尝试使用 FSharp 数据提供程序,但使用 npgsql 来对抗 Postgresql。我在第一行就失败了。

当我尝试创建 SqlDataConnection 时,它抛出错误消息“连接字符串不正确”。

The type provider 'Microsoft.FSharp.Data.TypeProviders.DesignTime.DataProviders' reported an error: Keyword not supported: 'port:5432;database'.

现在,我使用 Servicestack.Ormlite 测试连接字符串和数据。这基本上使用 IdbConnection。所以,连接都是正确的。但我不知道为什么 Type Provider 不工作。

这是代码。

    //type dbSchema = SqlDataConnection<ConnectionString = "Server=localhost;Port=5432; Database=TestDB;User Id=postgres;Password=g00gle*92;" >
[<CLIMutable>]
type Person = 
    { ID : int;
      FirstName : string;
      LastName : string }

[<EntryPoint>]
let main args = 
    let dbFactory = 
        OrmLiteConnectionFactory
            (
             "Server=localhost;Port=5432; Database=TestDB;User Id=postgres;Password=*****;", 
             PostgreSqlDialect.Provider)
    use dbConnection = dbFactory.OpenDbConnection()
    Console.WriteLine dbConnection.State
    let persons = dbConnection.Select<Person>()
    persons.ForEach(fun p -> Console.WriteLine p.FirstName)
    Console.Read() |> ignore
    0

在上面的代码中,第一个注释行不起作用,而下面的代码使用相同的设置。这意味着问题仅与类型提供程序有关,与连接恕我直言无关。

我需要做任何其他设置吗?

如果需要任何其他详细信息,请告诉我。

更新

在 kvb 的评论之后,我都尝试了。这是带有网络配置的更新代码。

//type dbSchema = SqlEntityConnection<ConnectionStringName = "TestDB", Provider="Npgsql">
    type dbSchema = SqlEntityConnection< ConnectionStringName="TestDB" >

    [<CLIMutable>]
    type Person = 
        { ID : int;
          FirstName : string;
          LastName : string }

    [<EntryPoint>]
    let main args = 
        let dbFactory = 
            OrmLiteConnectionFactory
                (
                 "Server=localhost;Port=5432; Database=TestDB;User Id=postgres;Password=*******;", 
                 PostgreSqlDialect.Provider)
        use dbConnection = dbFactory.OpenDbConnection()
        Console.WriteLine dbConnection.State
        let persons = dbConnection.Select<Person>()
        persons.ForEach(fun p -> Console.WriteLine p.FirstName)
        Console.Read() |> ignore
        0

这是网页配置

  <system.data>
    <DbProviderFactories>
      <add name="Npgsql Data Provider"
            invariant="Npgsql"
            description="Data Provider for PostgreSQL"
            type="Npgsql.NpgsqlFactory, Npgsql" />
    </DbProviderFactories>
  </system.data>
  <connectionStrings>
    <add name="TestDB"
          connectionString="Server=localhost:5432; Database=TestDB;User Id=postgres;Password=******;"
          providerName="Npgsql" />

  </connectionStrings>

这里是 appconfig 中的程序集。我不认为它会在 GAC 中,因为我是通过 nuget 添加的

 <dependentAssembly>
    <assemblyIdentity name="Npgsql" publicKeyToken="5d8b90d52f46fda7" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-2.0.12.0" newVersion="2.0.12.0" />
 </dependentAssembly>

上面两个都被注释了,另一个没有被注释的都失败了,并出现了不同的错误。 第一个因错误而失败

The type provider 'Microsoft.FSharp.Data.TypeProviders.DesignTime.DataProviders' reported an error: Error reading schema. error 7001: The specified store provider 'Npgsql' cannot be found in the configuration, or 'Npgsql' is not valid. Unable to find the requested .Net Framework Data Provider. It may not be installed.

第二个是这个错误

The type provider 'Microsoft.FSharp.Data.TypeProviders.DesignTime.DataProviders' reported an error: Error reading schema. error 7001: The provider did not return a ProviderManifestToken string. A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) The network path was not found

我还是不明白为什么要搜索SQL server。

如果需要任何进一步的信息,请告诉我。

最佳答案

我将发布部分答案,希望有人能弄清楚下一步该怎么做。

将编译以下代码:

open Microsoft.FSharp.Data.TypeProviders
open System.Data.Entity // this is important -- you cannot see any tables without it

type internal dbSchema = 
    SqlEntityConnection<
        ConnectionString="Server=localhost;Database=testdb;User Id=postgres;Password=password;", 
        Provider="Npgsql">

[<EntryPoint>]
let main argv = 
    let context = dbSchema.GetDataContext()
    query { for item in context.test_table do
            select item }
    |> Seq.iter (fun item -> printfn "%A" item)
    0

数据库testdb中的表test_table通过

创建
CREATE TABLE test_table
(
  id integer NOT NULL,
  value text,
  CONSTRAINT "PK_test_x_Id" PRIMARY KEY (id)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE test_table
  OWNER TO postgres;

为此你需要做四件事:

  • GAC Npgsql.dll ("C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\x64\gacutil.exe"/i [文件名])
  • GAC Mono.Security.dll(与 NuGet 下载 Npgsql.dll 的目录相同
  • 将 DbProviderFactory 添加到您的 .NET 4 64 位 machine.config(“C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config”):与您在 app.config 中拥有的内容相同,但已添加到 machine.config 中的相应部分,我的目前有一个条目用于 Microsoft SQL Server Compact Data Provider。请记住包含正确的公钥 token 。
<system.data>
  <DbProviderFactories>
    <add name="Npgsql Data Provider"
      invariant="Npgsql"
      description="Data Provider for PostgreSQL"
      type="Npgsql.NpgsqlFactory, Npgsql, Version=2.0.12.0, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7" />
</DbProviderFactories>
</system.data>
  • 重新启动 Visual Studio 。

现在 SqlEntityConnection 在设计时编译,您将能够看到所有可用的表。这也将愉快地编译成可执行文件。

这回答了你的问题;但现在奇怪的是,这意味着你仍然不开心。当您运行这段代码时,它会在 dbSchema.GetDataContext() 被调用时抛出一个 ArgumentException 说:

The supplied connection string should be either a valid provider-specific connection string or a valid connection string accepted by the EntityClient.

内部异常状态

The 'server' keyword is not supported.

堆栈跟踪

at System.Data.EntityClient.EntityConnectionStringBuilder.set_Item(String keyword, Object value) at System.Data.Common.DbConnectionStringBuilder.set_ConnectionString(String value) at System.Data.EntityClient.EntityConnectionStringBuilder..ctor(String connectionString) at SqlEntityConnection1.dbSchema.GetDataContext()

我试过修改连接字符串以使其正常工作,但我认为这一定是提供程序在运行时和设计时创建连接字符串的方式中的错误。由于此代码被发送到动态程序集中,因此您如何查看代码以了解发生了什么并不明显。

关于postgresql - Postgresql 的 FSharp 数据类型提供程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17854039/

相关文章:

postgresql - 将第 1 列的平均值除以第 2 列的平均值

postgresql - 在postgresql中将间隔转换为数字

f# - 令人困惑的 F# 编译器消息

postgresql - 使用多个条件对分区进行排序

parsing - 如何在 VS2013 中运行 FParsec

generics - F# 中有没有办法编写一个可以接受 Tuple 或 Single 值的通用函数?

与旧的 ODBC 提供程序相比,PostgreSQL 的 .NET 提供程序运行缓慢

postgresql - 根据值元组过滤 Postgres 表

C#/Postgres/FluentNHibernate : configuring npgsql throws NotSupportedException

postgresql - 删除所有违反新的唯一约束的记录