我正在尝试使用 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/