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!
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>()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With