Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF saving with F# and ASP.NET MVC

Based on the great samples from Daniel Mohl and his book.

I have and ASP.NET MVC application in F# with the online template for it. So far I have my model, entities, controller, repository, view... all very generalized and reusable, and the querying is great. But I can't find a way to keep the saving to the DbContext part equally reusable.

For the querying part the code for Repository.fs is as follows

namespace Melopienso.Repositories

open System
open System.Linq

module Repository =
    let get (source:IQueryable<_>) queryFn =
        queryFn source |> Seq.toList

    let getAll () =
        fun s -> query { for x in s do
                         select x }

    let find filterPredFn =
        filterPredFn
        |> fun fn s -> query { for x in s do
                               where (fn()) }

    let getTop rowCount =
        rowCount
        |> fun cnt s -> query { for x in s do
                                take cnt }

........... (More Code) ...........

And in the controller I pass everything necessary:

namespace Melopienso.Controllers

open System
open System.Web.Mvc
open Melopienso.Models
open Melopienso.Repositories
open Repository
open Utils

[<HandleError>]
type CategoriesController(context:IDisposable, ?repository) =
    inherit Controller()

let fromRepository =
    match repository with
    | Some v -> v
    | _ -> (context :?> MelopiensoEntities).Categories
    |> Repository.get

new() = new CategoriesController(new MelopiensoEntities())

member this.Index () =
    getAll() |> fromRepository |> this.View

override x.Dispose disposing =
    context.Dispose()
    base.Dispose disposing

[<HttpGet>]
member this.Create () =
    this.View()

........... (More Code) ...........

Now, when saving the problem resides in how to make it as reusable as that. If I pass the DbSet I need a way to call the context, which I don't know how to find it from the specific DbSet (doubt it is even possible).

If I pass both the DbContext and DbSet, I can't do something like

use nameOfDbContext
    nameOfDbContext.NameOfDbSet.Add entity

The only option I find to hardcode anything, but that just doesn't seem right.

It's a shame but Daniel's great examples don't do the saving part in a "traditional" EF way and use buses, etc, which is great but I first would like to have a basic application fully working, and then improve from there with Async controllers, mailboxes, etc.

Any hint would be greatly appreciated. Cheers!

like image 825
Jacobo Polavieja Avatar asked Nov 13 '22 10:11

Jacobo Polavieja


1 Answers

Why can't you pass both the DbContext and the DbSet, and use the DbContext for saving, and access the DbSet directly (don't try and go through DbContext) for queries etc.?

You can also get a DbSet from a DbContext if you have the type, which might also help:

myDbContext.Set<'a>()
like image 135
Danny Tuppeny Avatar answered Nov 15 '22 11:11

Danny Tuppeny