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