Zaid-Ajaj / LiteDB.FSharp

Advanced F# Support for LiteDB, an embedded NoSql database for .NET with type-safe query expression through F# quotations
MIT License
181 stars 20 forks source link

minor differences in syntax from the doc, missing FindMany for collections, DbREf issue #20

Closed tonyx closed 6 years ago

tonyx commented 6 years ago

This is my configuration.

Versions:

minor differences in syntax:

result = albums.findOne <@ fun album -> album.Id = 1 @> does not typecheck, whereas the following does: result = albums.FindOne (fun album -> album.Id = 1)

findMany

Missing "findMany" (or "FindMany") method in collections

DbREf issue. Reference to the ref object is null :

in an example like the following:


open LiteDB.FSharp.Linq

[<CLIMutable>]
type Company=
  { Id : int
    Name : string}   

[<CLIMutable>]    
type Order=
  { Id :int
    Company :Company }

let mapper = FSharpBsonMapper()
mapper.DbRef<Order,_>(fun c -> c.Company)

I create and insert a company in its own collection, then I create an order having as the Company field with the newly created company as value. Then if I load again the order from the collection, the Company is null (i.e. "Object reference not set to an instance of an object"). The result is the same if I store in the Company field a company loaded from the collection, rather than a newly created one.

note: I haven' tried other features, like inheritance, yet.

humhei commented 6 years ago

With DbRef

Insertion: You should add a company first And then insert order with this company

Query: You should use inculde expression first to expand DBRef

See this test for deatil https://github.com/Zaid-Ajaj/LiteDB.FSharp/blob/master/LiteDB.FSharp.Tests/Tests.DBRef.fs#L46

    testCase "CLIType DBRef NestedId token Test" <| fun _ -> 
      useDatabase <| fun db ->
        let company = {Id = 1; Name = "InitializedCompanyName"}  
        let order = { Id = 1; Company = company; EOrders = []}
        db.Insert(company)
        db.Insert(order)
        let m = db.Query<Order>().Include(convertExpr <@ fun c -> c.Company @> ).FirstOrDefault()
        Expect.equal m.Company.Id 1 "CLIType DBRef NestedId token Test Corrently"  
Zaid-Ajaj commented 6 years ago

Hello @tonyx, how exactly does this result = albums.findOne <@ fun album -> album.Id = 1 @> not type-check? What error do you get?

tonyx commented 6 years ago

Hi @Zaid-Ajaj:

compile error: "error FS0039: The field, constructor or member 'findOne' is not defined. Maybe you want one of the following: FindOne"

the following compiles and works as expected instead: let first = users.FindOne(fun x -> x.Id = 1)

If I try to autocomplete starting typing Find I get: Find FindAll FindById FinOne

The method Find works ok to replace findMany:

let usersNamedJohn = users.Find (fun x -> x.UserName = "john") can return a sequence of the users matching the expression

Zaid-Ajaj commented 6 years ago

Aah you need to open LiteDB.FSharp.Extensions to get these lower-case functions. I didn't know that linq expressions could be adhoc-converted from fsharp functions automatically, hmm maybe they aren't needed at all

tonyx commented 6 years ago

👍