fsprojects / SQLProvider

A general F# SQL database erasing type provider, supporting LINQ queries, schema exploration, individuals, CRUD operations and much more besides.
https://fsprojects.github.io/SQLProvider
Other
570 stars 144 forks source link

[Question]: Possible to provide floats as single instead of double precision? #666

Closed varon closed 4 years ago

varon commented 4 years ago

Description

I'm working with a lot of data that eventually gets computed on the GPU, so using float32 in the application side is preferable.

Because the data comes back as double, the automatic mapping via MapTo<T> fails.

Is it possible to set some kind of global option that returns all floats as System.Single intead of System.Double?

Thorium commented 4 years ago

There are no current support for this out-of-the-box. I guess people just do "select (float mycol1, float mycol2)"

I will accept PR to just make MapTo not fail when casting. There is already a conversion-trial-system for procedure returns or something: https://github.com/fsprojects/SQLProvider/blob/8b5cb347f5e424b97f7ec87f36a52baf989c30cf/src/SQLProvider/Utils.fs#L73

I would be interested how do you use MapTo as I never used it myself, and people complain some features of it, but there are no unit-tests, so I cannot fix what I don't know it should work in the first place.

I guess what could also be doable, is configurable mapping of SQL-types (varies per database) to .NET types (1 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger)), e.g. via static parameter, but this is not a lot requested feature.

However, what I would really also like is kind of language level #pragma keyword to set your types: https://github.com/fsharp/fslang-suggestions/issues/737

Thorium commented 4 years ago

You can already provide optional type mapping parameter for MapTo-method.

Example to map EmployeeId from int64 database column to Int32 record:

type Employee = {
    EmployeeId : int32
    FirstName : string
    LastName : string
    HireDate : DateTime
}
let example() =
    query {
        for emp in dc.Main.Employees do
        select emp
        skip 2
        take 5
    } 
    |> Seq.map (fun e ->
        e.MapTo<Employee>(
            function
            | "EmployeeId", (:? int64 as id) -> Convert.ToInt32(id) |> box
            | k,v -> v))
    |> Seq.toList 

...and this is duplicate of #525