How to use an Id well in Classes, and save mutable values to LiteDB
See original GitHub issueHi @Zaid-Ajaj,
I would like to use an autoincremental Id also in Classes. In the documentation it is very well explained that when it comes to records we have to classify it as [<CLIMutable>] and put Id = 0 so that the Identifier autoincrements itself.
But that is not so established with the classes. I ask if there is a plan to do it also in classes?
In the meantime testing witdh this example class
type Article( Id: ObjectId, Name: string) as self =
let mutable mutableValue = 0
do
mutableValue <- 10
printfn "Initialized object"
// private mutable value
member val Id = Id //Read Only
member val Name = Name with get, set
// public wrapper for mutable value
member this.SetMutableValue x =
mutableValue <- x
The Id type set to ObjectId type and get one before inserting a new Article like this:
let myArticle = new Article(ObjectId.NewObjectId(), "title")
I’m not sure that’s the best way, since: let result = articles.FindById(myArticle.Id) shows the following error:
error FS0193: Type constraint mismatch. The type 'ObjectId' is not compatible with type 'BsonValue'.
I accept it’s not the right type and I try that way: let result = articles.findOne <@ fun a -> a.Id = myArticle.Id @>, and everything works until I change the = for another operator <= to: let result = articles.findOne <@ fun a -> a.Id <= myArticle.Id @> and get:
error FS0001: The type 'ObjectId' does not support the 'comparison' constraint. For example, it does not support the 'System.IComparable' interface
The only issue here is that I don’t know which is the correct way to use Id in a Class, if I want the DB to assign them automatically.
At the same time and with the class I’ve expounded before. Only the constructor parameters are stored in the DB, the let mutable mutableValue is not stored. Is there any way they persist in the database, which I’ve overlooked?
If this is the behavior designed, we adapt without problems. But I think it will be interesting for the product that these values are saved in the DB by default, and if you don’t want to apply them [<BsonIgnore>].
Thank you for everything. And it’s really great work you’re doing with LiteDB.FSharp.
Issue Analytics
- State:
- Created 4 years ago
- Comments:5 (1 by maintainers)

Top Related StackOverflow Question
Thanks @Zaid-Ajaj, @humhei It was misunderstood on my part. In a class with
Idasintwithoutgetandset, and that way you couldn’t assignIdfrom LiteDB. Then I tried to use ObjectID. By fixing that, as @humhei reminded me, you can useIdasint, and LiteDB assigns the number correlatively.You are right when you say that ObjetcID adds coupling, but if it’s used as a GUI. But as it is currently calculated as sequential, which will be the same as an int. https://github.com/mbdavid/LiteDB/wiki/Data-Structure
So the @humhei’s fix
has come in handy for all of us and is perfectly correct. Thanks guys.
As explained in #29 there is a reason that comparison operators don’t work with identities: it doesn’t make sense. The
Idproperty to identify a single record of data, not a range of records. Which is also whyObjectIDdoesn’t implementIComparable: it doesn’t need to.As for using classes in LiteDB.FSharp, I don’t know why you would do that because again this introduces tight coupling between the persistence layer (modeling the record types) with your business layer (modeling behavior in your classes). Trying to hide the lambda expressions to make the model “readable” by domain expects isn’t really a solution. Using classes is arguable less readable compared to just plain old functions:
I guess this answers your comment about domain modeling? (sorry I can’t find it anymore)
If you can get this library to work with classes, then that is fine but it is really out of scope of this library to support classes: not idiomatic F#. The documentation clarifies this in the readme file: