I'm learning F#, and in an attempt to become more fluent I am re-writing a backend/data access layer to a program that is currently using C# with an ORM. I'm using the SqlDataProvider type provider (and loving it btw).
My search for partial class type in F# didn't turn up with any promising results. The reason for the partial class is to add some base functionality to the database objects returned from the Sql type provider. So far I'm simply inheriting from the types returned from the Sql type provider, and adding functionality that way. However, when I return a query result from a function, its returning the base class, not the derived class.
I don't want to use reflection to map between the two objects' properties, but I also don't want to have to return a "new fooObject { ...... }" and list every single property every time I want to create a new method.
So here I am, at the source of all the is good in the world. Am I missing something that I can use for partial class creations? Is there an easy way (without using reflection) to map the returned object to the derived object? Am I missing some awesome functionality completely?
type DbContext = SqlDataConnection<ConnectionString="~">
//Database objects
type Address() =
//inheriting base class from SqlDataProvider
inherit DbContext.ServiceTypes.Address()
//Adding common functionality
member this.Add() =
use db = DbContext.GetDataContext()
db.Address.InsertOnSubmit this
db.DataContext.SubmitChanges()
member this.Remove() =
use db = DbContext.GetDataContext()
db.Address.DeleteOnSubmit this
db.DataContext.SubmitChanges()
member this.Update() =
use db = DbContext.GetDataContext()
let mutable old = query {for a in db.Address do
where (a.AddressId = this.AddressId)}
|> Seq.exactlyOne
old <- this
db.Address.Context.SubmitChanges()
//this method only returns the base object
static member GetAll() =
use db = DbContext.GetDataContext()
db.Address |> Seq.toList
//as does this one
static member Find addressId =
use db = DbContext.GetDataContext()
let add = new Address()
query {for a in db.Address do where (a.AddressId = addressId)}
|> Seq.exactlyOne
F# does this kind of thing with type extensions:
Note that type extensions (in this format) are only accessible from F# code. If you need something interoperable with C#/VB.Net, you should instead use 'normal' extension methods:
As for the
GetAllandFindmethods, I would be tempted to create a module with functions likeGetAllAddressesandFindAddress.Overall, the repository pattern is kind of awkard in F#.