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
180 stars 22 forks source link

Unhandled Exception-Method not found: ..LiteRepository.Insert... at ...FSharp.Extensions.LiteRepository.insertItem... #25

Closed srlopez closed 5 years ago

srlopez commented 5 years ago

Continuing with my first steps, I find that I still need to include some module. I get the following error addressed from the following line: LiteRepository.insertItem eorder

Unhandled Exception: System.MissingMethodException: Method not found: 'Void LiteDB.LiteRepository.Insert(System.__Canon, System.String)'.
   at LiteDB.FSharp.Extensions.LiteRepository.insertItem[a](a item, LiteRepository lr)
   at Program.main(String[] argv) in /app/appbook/Program.fs:line 248
    let eorder = { Id = 1; Items = [item1;item2];  OrderNumRange = "" }

    let queryedEOrder =
        db 
        |> LiteRepository.insertItem eorder
        |> LiteRepository.query<EOrder> 
        |> LiteQueryable.first

    match queryedEOrder.Items with 
    | [item1;item2] -> 
        match item1,item2 with 
        | :? IBarcode,:? IColor -> 
            pass()
        | _ -> fail()   
    | _ -> fail()

    printfn "Hello World from F#!"
    0 // return an integer exit code
Zaid-Ajaj commented 5 years ago

Hmm looks like a nasty exception we got here, this is usually due to assemblies not properly loaded. I will need a bit more information:

srlopez commented 5 years ago

On my fsproj file the References version are:

    <PackageReference Include="LiteDB" Version="4.1.4" />
    <PackageReference Include="LiteDB.FSharp" Version="2.7.0" />

And this are the version

$ dotnet --version
2.2.203
$ uname -a
Linux SAFE 4.15.0-47-generic #50-Ubuntu SMP Wed Mar 13 10:44:52 UTC 2019 x86_64 GNU/Linux

May be an issue with use db = new LiteDatabase("simple.db", mapper) and use db = new LiteRepository(memoryStream, mapper). I just try yo reproduce and integrate your examples on README.md in a fs file.

The full code:

// Learn more about F# at http://fsharp.org
open System
open System.IO

open LiteDB
open LiteDB.FSharp
open LiteDB.FSharp.Linq
open LiteDB.FSharp.Extensions

let pass() = printfn "passed" 
let fail() = printfn "failed"

type IItem =
    abstract member Id : int
    abstract member Art : string
    abstract member Name : string
    abstract member Number : int

type IBarcode =
    abstract member Barcode : string

type ISize =
    abstract member Size : int

type IColor =
    abstract member Color : string

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

[<CLIMutable>]    
type EOrder=
  { Id: int
    Items : IItem list
    OrderNumRange: string }   

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

type Item1 =
    /// val mutable will make field serializable and deserializable
    val mutable Id : int
    val mutable Art : string
    val mutable Name : string
    val mutable Number : int

    interface IItem with 
        member this.Art = this.Art
        member this.Id = this.Id
        member this.Name = this.Name
        member this.Number = this.Number
    val mutable Barcode : string

    interface IBarcode with 
        member this.Barcode = this.Barcode    
    new (id, art, name, number, barcode) =
        { Id = id; Art = art; Name = name; Number = number; Barcode = barcode }

type Item2 = 
    val mutable Id : int
    val mutable Art : string
    val mutable Name : string
    val mutable Number : int

    interface IItem with 
        member this.Art = this.Art
        member this.Id = this.Id
        member this.Name = this.Name
        member this.Number = this.Number

    val mutable Size : int
    interface ISize with 
        member this.Size = this.Size 
    val mutable Color : string

    interface IColor with 
        member this.Color = this.Color 

    new (id, art, name, number, size, color) =
        { Id = id; Art = art; Name = name; Number = number; Size = size; Color = color }

FSharpBsonMapper.RegisterInheritedConverterType<IItem,Item1>()
FSharpBsonMapper.RegisterInheritedConverterType<IItem,Item2>()

[<EntryPoint>]
let main argv =
    let mapper = FSharpBsonMapper()
    use db = new LiteDatabase("simple.db", mapper) // <-----
    let company = {Id = 1; Name = "InitializedCompanyName"}  
    let order = { Id = 1; Company = company; EOrders = []}
    mapper.DbRef<Order,_>(fun c -> c.Company)
    mapper.DbRef<Order,_>(fun c -> c.EOrders)
    use memoryStream = new MemoryStream()
    use db = new LiteRepository(memoryStream, mapper) // <-----
    db.Insert(company) |> ignore
    db.Insert(order)   |> ignore

    let item1 = 
        Item1 ( 
            id = 0,
            art = "art",
            name = "name",
            number = 1000,
            barcode = "7254301" 
        )

    let item2 = 
        Item2 ( 
            id = 0,
            art = "art",
            name = "name",
            number = 1000,
            color = "red" ,
            size = 39 
        )

    let eorder = { Id = 1; Items = [item1;item2];  OrderNumRange = "" }

    let queryedEOrder =
        db 
        |> LiteRepository.insertItem eorder
        |> LiteRepository.query<EOrder> 
        |> LiteQueryable.first

    match queryedEOrder.Items with 
    | [item1;item2] -> 
        match item1,item2 with 
        | :? IBarcode,:? IColor -> 
            pass()
        | _ -> fail()   
    | _ -> fail()

    printfn "Hello World from F#!"
    0 // return an integer exit code
Zaid-Ajaj commented 5 years ago

Thanks a lot @srlopez, I will investigate this further. Though these example should have worked because they are all unit-tested.

Zaid-Ajaj commented 5 years ago

Found it, you are using incompatible versions of LiteDB and LiteDB.FSharp:

<PackageReference Include="LiteDB" Version="4.1.4" />
<PackageReference Include="LiteDB.FSharp" Version="2.7.0" />

The fix is to remove <PackageReference Include="LiteDB" Version="4.1.4" /> from your package references and run dotnet restore && dotnet run because the right version will be pulled in a dependency of LiteDB.FSharp, so your project file will look something like:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <Compile Include="Program.fs" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="LiteDB.FSharp" Version="2.7.0" />
  </ItemGroup>

</Project>

Can you please confirm the fix when you remove the LiteDB package reference and run dotnet restore && dotnet run, I will close the issue for now, please re-open if the problem persists.

srlopez commented 5 years ago

Confirmed & Thanks! Removing <PackageReference Include="LiteDB" Version="4.1.4" /> from app.fsproj and dotnet restore && dotnet run print passed! on the screen:

dotnet restore && dotnet run
  Restore completed in 3.95 sec for /app/appbook.fsproj.
passed
Hello World from F#!

Thanks