Design of sql data layer

I’m working on a console application that needs to read/write to a Postgres database. How do you design a data layer in this case? I’m currently using SQLProvider (after trying EF Core and Npgsql.FSharp) which is simply wonderful. I’ve gone through a few designs while trying to build a clean data layer. I’ve settled on this currently:

module Database

// represents entities to store
type StoreEntity =
    | StoreSeason of newSeason: NewSeason
    | StoreDivision of newDivision: NewDivision
    | StoreRequest of newRequest: NewRequest

and NewSeason =
    { StartYear: Domain.Year
    EndYear: Domain.Year
    CreatedDate: DateTime }

and NewDivision =
    { CreatedDate: DateTime
    SeasonId: Domain.SeasonId
    ExternalDivisionId: Domain.ExternalDivisionId
    DivisionName: Domain.DivisionName }

and NewRequest =
    { Request: Domain.HttpRequestDefinition
    RequestDate: DateTime
    Response: Domain.HttpResponseDefinition
    ResponseDate: DateTime }

// database gateway
type Gateway(databaseConnection: DatabaseConnection) =

    // insert new entity
    member this.Insert storeEntity =
        let ctx =
            DatabaseProvider.GetDataContext(databaseConnection.Format())

        // all "handlers" are expected to return the primary key (int)
        let id =
            match storeEntity with
            | StoreSeason s -> this.StoreSeason ctx s
            | StoreDivision d -> this.StoreDivision ctx d
            | StoreRequest r -> this.StoreRequest ctx r

        id

    // rest is the entity "handlers"...

    member private this.StoreSeason ctx item =
        let entity =
            ctx.xxx.Create(
                ...
            )
        ctx.SubmitUpdates()

        entity.SeasonId

    member private this.StoreRequest ctx item =
        let entity =
            ctx.xxx.Create(
                ...
            )
        ctx.SubmitUpdates()

        entity.RequestId

    member private _.StoreDivision ctx d =
        let entity =
            ctx.xxx.Create(
                ...
            )
        ctx.SubmitUpdates()

        entity.DivisionId

What I like about this approach is that I have a single place where the context is created (useful for logging, transactions, etc). It also looks a bit like command handlers, which I’m used to in C#. I also like the fact that the primary key is returned, which is usually needed for the next step. I am not entirely sure how this will evolve when the number of entites increase. I might have to pull out the handlers into another class, to keep line count down. I can envisage updates being handled in a very similar way, just not returning anything and specifying the primary key along with the StoreEntity items. I don’t like to repeat SubmitUpdates in each handler, will need to find another way.

How do you design a similar data layer for a sql database?