Logo




Subscribe:
RSS 2.0 | Atom 1.0
Categories:

Sign In


[Giagnocavo]Michael::Write()

# Thursday, April 23, 2009
Update on F# with Fluent NHibernate

Last time, I hacked up some rudimentary support for F# and Fluent NHibernate. It really looked ugly. I looked into what I could do to make it not look as sucky.

First off, having to write a full lambda for each mapping was annoying. F# quotations don't have to be lambdas, unlike C#'s expressions. So, instead of having to write, say, "fun x -> x.Foo", we can write "x.Foo", assuming there's a local variable x with the right type. The ClassMap subclass now expects these types of quotations than full lambdas.

Next, I experimented with using type extensions to overload functions like Id and Map, however I found out that F#, at least currently, does not add in type extensions for overload resolution. So I ended up having a new subclass of ClassMap<T>, 'T ClassMapQ. I used the Q suffix consistently to denote "quotations". I added type extensions for most of the other mapping types so that quotations could be used.

As to the question of having to tag on " |> ignore " to each mapping, I decided to write an extension propery for IMappingPart called Done, which is simply unit. Finally, the problem of lazy loading I took care of by setting "use_proxy_validator" to false, as mentioned here. The end result is that this mapping code:

type StoreMap() = inherit ClassMap<Store>() do
    base.Not.LazyLoad()
    base.Id ~@@ <@ fun x -> x.Id @> |> ignore
    base.Map ~@@ <@ fun x -> x.Name @> |> ignore

    (base.HasManyX <@ fun x -> upcast x.Staff @>)
        .LazyLoad()
        .Inverse().Cascade.All() |> ignore
    (base.HasManyToManyX <@ fun x -> upcast x.Products @>)
        .Cascade.All()
        .WithTableName("StoreProduct") |> ignore

Is now:

type StoreMap() as m = inherit ClassMapQ<Store>() do
    let x = m.DefaultX
    (m.IdQ <@ x.Id @>).Done
    (m.MapQ <@ x.Name @>).Done
    (m.HasManyQ <@ seq x.Staff @>)
        .LazyLoad()
        .Inverse().Cascade.All()
        .Done
    (m.HasManyToManyQ <@ seq x.Products @>)
        .LazyLoad()
        .Cascade.All()
        .WithTableName("StoreProduct")
        .Done

This is pretty enough that I'm satisfied with how well F# interops. Most of the things I figured out here will apply to other .NET OO APIs, not just this one.

I am hoping that VS2010 Beta 1 will ship soon, as F# is getting some interesting upgrades then. With that, it should be easier to extend the support to other parts of NHibernate, such as querying, and perhaps integrate in NHibernate.Linq.

FSharp
Thursday, April 23, 2009 7:06:45 PM UTC  #    Comments [0]  |  Trackback

OpenID
Please login with either your OpenID above, or your details below.
Name
E-mail
Home page

Comment (HTML not allowed)  

Enter the code shown (prevents robots):

Live Comment Preview