Why is FSharp.Data.SqlClient record exposed as object?

217 views Asked by At

I'm working on a demo where I can show how easy it is to use the SqlClient type provider in a F# library and then consume it from C#, I think this might be one way to get things into projects. Since many people using C# want to use interfaces etc. I thought I show them that it is possible to combine everything, but I don't get the expected result. I have the following F# code which works as expected in F#:

module Orders = 
    [<Literal>]
    let connStr = """XXXXXXXXXXXX"""
    type OrdersPerEmployee = SqlCommandProvider<"OrdersPerEmployee.sql", connStr>

open Orders
type IOrdersRepo =
    abstract member getOrdersPerEmployee : int -> OrdersPerEmployee.Record seq
type OrdersRepo() =
    interface IOrdersRepo with
        member this.getOrdersPerEmployee(employeeId) = 
            let query = new OrdersPerEmployee()
            query.Execute(employeeId)

But when I try to use it from my C# app I don't get that the getOrdersPerEmployee returns an enumerable of records, instead it returns an enumerable of objects:

IOrdersRepo repo = new OrdersRepo();
var data = repo.getOrdersPerEmployee(4).ToList();
data.ForEach(y => Console.WriteLine(y));
Console.ReadLine();

In the code above I expceted to get intellisense on y in the lambda, but nothing. Any ideas?

1

There are 1 answers

4
Dmitry Morozov On BEST ANSWER

Because SqlCommandProvider is erasing types kind. It means types it generates can be consumed only from F#. Contrary, SqlEnumProvider from the same FSharp.Data.SqlClient library is generated types kind and can be consumed by C# (via proxy project). It works especially nice when CLIEnum=true. For a deeper discussion on erased vs generated types see How do I create an F# Type Provider that can be used from C#?