question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Single Case Discriminated Unions as Identifiers

See original GitHub issue

I am just playing around with the library and it works great so far. In the concrete use case I am considering to use it, however, we are using single case discriminated unions for ids quite heavily. The good news: Inserting records which use a DU as id works.

But I noticed that querying for a record that has just been inserted does not work. Also indexing isn’t working. Sample:

open System
open System.IO
open LiteDB
open LiteDB.FSharp

type FooId = FooId of Guid

type Foo = 
    { Id : FooId
      ParentId : FooId option }

[<EntryPoint>]
let main argv =
    let mapper = FSharpBsonMapper()
    let path = Path.Combine(Directory.GetCurrentDirectory(), "test.db")
    use db = new LiteDatabase(path, mapper)
    
    let id = Guid.NewGuid()
    
    let demoFoo =
      { Id = FooId(id)
        ParentId = None }
    
    let collection = db.GetCollection<Foo>()
    
    collection.Insert(demoFoo) |> ignore
    let indexEnsured = collection.EnsureIndex(fun x -> x.Id)
    printfn "Index ensured: %b" indexEnsured
    
    let allFoos = collection.FindAll() |> Seq.toList
    printfn "Total: %i" allFoos.Length
    
    let result = collection.FindById(BsonValue(id))
    printfn "Last one: %s" (result.Id.ToString())
    0

collection.FindById(BsonValue(id)) will just return null, indexEnsured is false.

When removing the DU and using theGuid directly, everything works as expected.

open System
open System.IO
open LiteDB
open LiteDB.FSharp

type FooId = FooId of Guid

type Foo = 
    { Id : Guid
      ParentId : FooId option }

[<EntryPoint>]
let main argv =
    let mapper = FSharpBsonMapper()
    let path = Path.Combine(Directory.GetCurrentDirectory(), "test.db")
    use db = new LiteDatabase(path, mapper)
    
    let id = Guid.NewGuid()
    
    let demoFoo =
      { Id = id
        ParentId = None }
    
    let collection = db.GetCollection<Foo>()
    
    collection.Insert(demoFoo) |> ignore
    let indexEnsured = collection.EnsureIndex(fun x -> x.Id)
    printfn "Index ensured: %b" indexEnsured
    
    let allFoos = collection.FindAll() |> Seq.toList
    printfn "Total: %i" allFoos.Length
    
    let result = collection.FindById(BsonValue(id))
    printfn "Last one: %s" (result.Id.ToString())
    0

Do you think there is a way to teach the mapper how to handle DU’s for such a case?

Thomas

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:11 (11 by maintainers)

github_iconTop GitHub Comments

1reaction
aspnetdecommented, Mar 2, 2020

I think we can consider this done 👍

1reaction
Zaid-Ajajcommented, Oct 7, 2019

I wondered if the readme is wrong or why all the methods are written in lower case there - now I know 😉

I used lower case functions for fsharp queries to distinguish them from the ones used with C# (upper case). You should almost always use the lower case ones.

Doing so results in an exception, as a DU isn’t a proper BsonValue.

My bad, should be fixed now, update nuget from 2.13.0 -> 2.14.0

Read more comments on GitHub >

github_iconTop Results From Across the Web

Designing with types: Single case union types
The answer is generally the single case discriminated union. It is much easier to “wrap” and “unwrap”, as the “union case” is actually...
Read more >
Alternate Ways of Creating Single Case Discriminated ...
In this post, we have seen a few styles of single case discriminated unions and records to wrap up primatives. It is pretty...
Read more >
Discriminated Unions - F# | Microsoft Learn
Discriminated unions provide support for values that can be one of a number of named cases, possibly each with different values and types....
Read more >
Discriminated Unions · F# for Fun and Profit - swlaschin
In F#, a sum type is called a "discriminated union" type. Each component type (called a union case) must be tagged with a...
Read more >
f# - Does using single-case discriminated union types have ...
Yes, there's going to be a performance drop when using single-case union types to wrap primitive values. Union cases are compiled into ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found