Поставщик типов данных FSharp для Postgresql

Я пытался поставщик данных FSharp, но против Postgresql с помощью npgsql. И я провалился на первой же строчке.

когда я пытаюсь создать SqlDataConnection, он выдает ошибку с сообщением, что строка подключения неверна.

провайдер типа 'Майкрософт.FSharp.Данные.TypeProviders.Время разработки.DataProviders' сообщение об ошибке: Ключевое слово не поддерживается: "порт: 5432; база данных".

теперь я тестирую строку подключения, а также данные с помощью 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

в приведенном выше коде первая прокомментированная строка не работает, а с теми же настройками ниже кода работает. Это означает, что проблема только с типом provider не с подключениями IMHO.

мне нужно сделать какие-либо другие настройки.

пожалуйста, дайте мне знать, если любые другие детали требуемый.

обновление

после комментария kvb я попробовал оба. Вот обновленный код с web config.

//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

а вот web config

  <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>

выше обоих один комментируется, а другой, без которого не комментируется, терпит неудачу с другой ошибкой. Первая ошибка

провайдер типа 'Майкрософт.FSharp.Данные.TypeProviders.Время разработки.DataProviders' сообщение об ошибке: ошибка чтения схемы. ошибка 7001: указанное Npgsql поставщика магазин '' не может быть найден в конфигурации или 'Npgsql' недопустим. Не удалось найти запрошенную платформу .Net Framework поставщик данных. Он не может быть установлен.

и второй-с этой ошибки

провайдер типа 'Майкрософт.FSharp.Данные.TypeProviders.Время разработки.DataProviders' сообщение об ошибке: ошибка чтения схемы. ошибка 7001: поставщик сделал не возвращайте строку ProviderManifestToken. Связанная с сетью или при установлении соединения с экземпляром произошла ошибка SQL-сервер. Сервер не найден или недоступен. Проверить что имя экземпляра является правильным и что SQL Server настроен на разрешить удаленные подключения. (поставщик: поставщик именованных каналов, ошибка: 40 - Не могла откройте соединение с SQL Server) сетевой путь не был найдено

Я до сих пор не понимаю, почему он ищет SQL server.

пожалуйста, дайте мне знать, если требуется дополнительная информация.

2 ответов


Я собираюсь опубликовать частичный ответ в надежде, что кто-то может решить, как сделать следующий бит.

следующий код будет компилироваться:

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

в таблице test_table в базе testdb создал через

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 [filename])
  • GAC Mono.Безопасность.dll (в том же каталоге, что и Npgsql.dll был загружен в NuGet
  • добавить DbProviderFactory для вашей 64-разрядной машины .NET 4.config ("C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config"): это то же самое, что у вас есть в вашем приложении.config, но добавлен в соответствующий раздел в machine.config, у меня есть одна запись на данный момент для Microsoft SQL Server Compact Data Provider. Не забудьте указать правильный токен открытого ключа.
<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 компилируйте во время разработки, и вы сможете увидеть все доступные таблицы. Это также с радостью скомпилируется в исполняемый файл.

это отвечает на ваш вопрос; но теперь для странного бит, который будет означать, что вы все еще не счастливы. Когда вы запустите этот код, он выдаст ArgumentException как только dbSchema.GetDataContext() называется, говоря:

данная строка подключения должна быть действительный поставщика строка подключения или соединения строку приняты entityclient создан.

внутреннее исключение государства

ключевое слово 'server' не поддерживается.

С помощью stack-trace

в систему.Данные.поставщик EntityClient.EntityConnectionStringBuilder.set_Item (ключевое слово String, значение объекта) в системе.Данные.Общий.DbConnectionStringBuilder.set_ConnectionString(строковое значение) в системе.Данные.поставщик EntityClient.EntityConnectionStringBuilder..ctor (строка connectionString) на SqlEntityConnection1.практическое руководство.GetDataContext()

Я попытался охренеть строку подключения, чтобы заставить ее работать, но я думаю, что это должно быть ошибка в том, как поставщик создает строку подключения во время выполнения против времени разработки. Поскольку этот код испускается в динамическую сборку, не очевидно, как вы могли бы посмотреть на код, чтобы увидеть, что происходит.


я встречаю ту же трудность. Это исправлено, добавив это в приложение.конфигурационный файл :

<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
  <parameters>
    <parameter value="v11.0" />
  </parameters>
</defaultConnectionFactory>
<providers>
  <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
  <provider invariantName="Npgsql" type="Npgsql.NpgsqlServices, Npgsql.EntityFramework" />
</providers>