如何在F#中使用Entity Framework内存数据库?

时间:2019-04-15 09:44:58

标签: .net-core f# entity-framework-core in-memory-database

对于一个非常简单的用例,我正在尝试将F#的Entity Framework Core与内存数据库一起使用:

f1 <- function(x, overall_len, chars_repeat) {
    l1 <- rep(list(x), (overall_len / chars_repeat))
    res <- paste(sapply(l1, function(i)
        paste0(i, paste0(sample(letters[1:4], size = chars_repeat, replace = TRUE), collapse = ''),
        collapse = '')),
        collapse = '')
    return(res)
}

f1('WQ', 32, 8)
#[1] "WQcccdddacWQbacccabcWQccaaaaaaWQabbcddcb"
f1('BC', 20, 4)
#[1] "BCbdbcBCacbdBCdacbBCdbbaBCaccd"
f1('BC', 20, 10)
#[1] "BCdbbabacccaBCbabdbbbaac"
f1('AAA', 40, 5)
#[1] "AAAabcacAAAdbcbcAAAbdbdcAAAadcdcAAAcadbdAAAddaacAAAadcabAAAdbabb"

但它不起作用并引发以下异常:

let data = try Data.init(contentsOf: url, options:NSData.ReadingOptions.alwaysMapped)

我如何使它工作,存在OnConfiguring覆盖,所以我并不是我真正想念的东西。

2 个答案:

答案 0 :(得分:3)

一个猜测,我想知道这行是否是罪魁祸首:

if optionsBuilder.IsConfigured <> false then
            optionsBuilder.UseInMemoryDatabase("database_name") |> ignore

OnConfiguring仅应在每个DbContext实例中由EFCore调用一次,因此此处可能不需要检查IsConfigured。尝试删除该if分支,然后重试?

答案 1 :(得分:0)

有几个问题:

  • 正如Matthew Abbott指出的那样,OnConfiguring方法未正确实施,需要检查是否尚未配置(与我最初所做的相反)
  • 似乎我的实体定义中只需要简单的类型,而没有复杂的类型(因为将被视为另一个实体

解决方案:

open System
open Microsoft.EntityFrameworkCore


[<CLIMutable>]
type Airport = {
    Id: Guid
    Name: string
    X: double
    Y: double
}

type MyContext =
    inherit DbContext

    new() = { inherit DbContext() }
    new(options: DbContextOptions<MyContext>) = { inherit DbContext(options) }

    override __.OnConfiguring optionsBuilder =
        if optionsBuilder.IsConfigured <> true then
            optionsBuilder.UseInMemoryDatabase("database_name") |> ignore

    [<DefaultValue>]
    val mutable airports: DbSet<Airport>
    member x.Airports
        with get() = x.airports
        and set value = x.airports <- value

module AirportRepository =
    let getAirport id =
        use context = new MyContext()
        query {
            for airport in context.Airports do
                where (airport.Id = id)
                select airport
                exactlyOne
        } |> (fun x -> if box x = null then None else Some x)

    let addAirport (entity: Airport) =
        use context = new MyContext()
        context.Airports.Add(entity) |> ignore
        context.SaveChanges true |> ignore

[<EntryPoint>]
let main argv =
    let myGuid = Guid.NewGuid()
    let airport = {
        Id = myGuid
        Name = "Michelle"
        X = 42.0
        Y = 42.0
    }
    AirportRepository.addAirport airport
    let thisAirport = AirportRepository.getAirport myGuid
    assert (thisAirport = Some airport)
    0