F#:Marten不加载聚合

时间:2019-06-06 14:40:51

标签: c# f# marten

我正在将C#中Marten的示例改编为F#,但奇怪的是,我无法真正获得正确的聚合值:

open System
open Marten
open Marten.Schema.Identity

type AccountCreation = {
    Owner: string
    AccountId: Guid
    CreatedAt: DateTimeOffset
    StartingBalance: decimal
}

type Transaction = {
    To: Guid
    From: Guid
    Description: string
    Time: DateTimeOffset
    Amount: decimal
}

type AccountEvent =
    | AccountCreated of AccountCreation
    | AccountCredited of Transaction
    | AccountDebited of Transaction

type Account() =
    member val Id = Unchecked.defaultof<Guid> with get,set
    member val Owner = Unchecked.defaultof<string> with get,set
    member val Balance = Unchecked.defaultof<decimal> with get,set
    member val CreatedAt = Unchecked.defaultof<DateTimeOffset> with get,set
    member val UpdatedAt = Unchecked.defaultof<DateTimeOffset> with get,set

    member this.Apply(accountEvent: AccountEvent) =
        match accountEvent with
        | AccountEvent.AccountCreated accountCreation ->
            this.Id <- accountCreation.AccountId
            this.Owner <- accountCreation.Owner
            this.Balance <- accountCreation.StartingBalance
            this.CreatedAt <- accountCreation.CreatedAt
            this.UpdatedAt <- accountCreation.CreatedAt
        | _ -> ()

[<EntryPoint>]
let main argv =
    use store = DocumentStore.For(fun options ->
            let connectionString = sprintf "host=%s;database=%s;username=%s;password=%s"
                                       "localhost"
                                       "postgres"
                                       "root"
                                       "root"
            options.Connection(connectionString)
            options.Events.AddEventType(typeof<AccountEvent>)
            options.Events.InlineProjections.AggregateStreamsWith<Account>() |> ignore
        )

    use session = store.LightweightSession()

    let khalidId = CombGuidIdGeneration.NewGuid()

    let khalid = AccountEvent.AccountCreated({
        Owner = "Khalid Abuhakmeh"
        AccountId = khalidId
        StartingBalance = 1000m
        CreatedAt = DateTimeOffset.UtcNow
    })

    session.Events.Append(khalidId, khalid) |> ignore

    session.SaveChangesAsync()
    |> Async.AwaitTask
    |> Async.RunSynchronously

    let account = session.LoadAsync<Account>(khalidId)
                    |> Async.AwaitTask
                    |> Async.RunSynchronously

    let stream = session.Events.FetchStream(khalidId)

    printfn "%A" account
    printfn "%A" stream

    0

问题是,当请求与具有相关ID的聚合相对应的文档时,它仅返回null

let account = session.LoadAsync<Account>(khalidId)
                |> Async.AwaitTask
                |> Async.RunSynchronously

奇怪地获取事件流会按预期返回事件:

let stream = session.Events.FetchStream(khalidId)

这就像从未构建或存储投影一样,因此从未调用Account聚合Apply方法。

来源:Marten - Projections


[编辑]

事实证明,如果我不使用有区别的联合,而直接使用不同案例的类型,那么它将起作用:

open System
open Marten
open Marten.Schema.Identity

type AccountCreation = {
    Owner: string
    AccountId: Guid
    CreatedAt: DateTimeOffset
    StartingBalance: decimal
}

type Transaction = {
    To: Guid
    From: Guid
    Description: string
    Time: DateTimeOffset
    Amount: decimal
}

type AccountEvent =
    | AccountCreated of AccountCreation
    | AccountCredited of Transaction
    | AccountDebited of Transaction

type Account() =
    member val Id = Unchecked.defaultof<Guid> with get,set
    member val Owner = Unchecked.defaultof<string> with get,set
    member val Balance = Unchecked.defaultof<decimal> with get,set
    member val CreatedAt = Unchecked.defaultof<DateTimeOffset> with get,set
    member val UpdatedAt = Unchecked.defaultof<DateTimeOffset> with get,set

    member this.Apply(accountCreation: AccountCreation) =
        this.Id <- accountCreation.AccountId
        this.Owner <- accountCreation.Owner
        this.Balance <- accountCreation.StartingBalance
        this.CreatedAt <- accountCreation.CreatedAt
        this.UpdatedAt <- accountCreation.CreatedAt

[<EntryPoint>]
let main argv =
    use store = DocumentStore.For(fun options ->
            let connectionString = sprintf "host=%s;database=%s;username=%s;password=%s"
                                       "localhost"
                                       "postgres"
                                       "root"
                                       "root"
            options.Connection(connectionString)
            options.Events.AddEventType(typeof<AccountCreation>)
            options.Events.AddEventType(typeof<Transaction>)
            options.Events.InlineProjections.AggregateStreamsWith<Account>() |> ignore
        )

    use session = store.LightweightSession()

    let khalidId = CombGuidIdGeneration.NewGuid()

    let khalid = {
        Owner = "Khalid Abuhakmeh"
        AccountId = khalidId
        StartingBalance = 1000m
        CreatedAt = DateTimeOffset.UtcNow
    }

    session.Events.Append(khalidId, khalid) |> ignore

    session.SaveChangesAsync()
    |> Async.AwaitTask
    |> Async.RunSynchronously

    let account = session.LoadAsync<Account>(khalidId)
                    |> Async.AwaitTask
                    |> Async.RunSynchronously

    let stream = session.Events.FetchStream(khalidId)

    printfn "%A" account
    printfn "%A" stream

    0

[编辑] 我在GitHub上发布了一个问题:https://github.com/JasperFx/marten/issues/1283

0 个答案:

没有答案