Как использовать этот асинхронный метод EF Core C # в F #? - PullRequest
1 голос
/ 16 апреля 2019

Я использую F # с Entity Framework и не могу понять, как использовать асинхронные методы C # из F #.Несмотря на другие, ТАК ответы, связанные с подобными проблемами, не могут действительно прийти в голову.

Вот моя попытка с кодом ниже, первоначально синхронным:

let getAirport (id: Guid) =
    use context = new MyContext()
    context.Flights.Find id
    |> (fun x -> if box x = null then None else Some x)

И его async аналог:

let getAirportAsync (id: Guid) =
    async {
        use context = new MyContext()
        let! flight = context.Airports.FindAsync id |> Async.AwaitTask
        return (fun x -> if box x = null then None else Some x)
    }

Однако, когда оба вызываются в основном:

[<EntryPoint>]
let main argv =
    let myGuid = Guid.NewGuid()
    let airport = {
        Id = myGuid
        Name = "Michelle"
        X = 42.0
        Y = 42.0
    }
    AirportRepository.addAirport airport
    let thisAirport = AirportRepository.getAirport myGuid
    let thisAirportToo = AirportRepository.getAirportAsync myGuid |> Async.RunSynchronously
    assert (thisAirport = Some airport)
    assert (thisAirportToo = Some airport)
    0

Невозможно скомпилировать:

  Program.fs(61, 13): [FS0001] The type '('a -> 'a option)' does not support the 'equality' constraint because it is a function type
  Program.fs(61, 30): [FS0001] This expression was expected to have type    ''a -> 'a option'    but here has type    ''b option'

Я прочитал:

Я думал, что процессиспользовать метод async C #:

  • Передать метод C # в |> Async.AwaitTask
  • Передать результат в let!
  • Вернуть этот результат
  • Обернуть все в блок async, который образует тело функции async F #
  • Используйте только что созданную async функцию F #, передав ее в |> Async.RunSynchronously

Что мне здесь не хватает?

1 Ответ

3 голосов
/ 16 апреля 2019

Проблема в том, что в getAirportAsync вы отбрасываете flight и просто возвращаете функцию. Исправление просто:

let getAirportAsync (id: Guid) =
    async {
        use context = new MyContext()
        let! flight = context.Airports.FindAsync id |> Async.AwaitTask
        return if box flight = null then None else Some flight
    }
...