Hey there, I've started to play around with Fluent NHibernate and now I want to could do something like IDbSet<T> like I could in EF Code First.. However I cant find any equivalent interface?
Thanks in adavance!
In NHibernate you operate with entities through the ISession interface (reference docs with example). You may wrap the session in a repository if you want (example: Sharp Architecture repository)
Related
I'm currently trying out a few different ways of implementing repositories in the project I'm working on, and currently have a single repository with generic methods on it something like this:
public interface IRepository
{
T GetSingle<T>(IQueryBase<T> query) where T : BaseEntity;
IQueryable<T> GetList<T>(IQueryBase<T> query) where T : BaseEntity;
T Get<T>(int id) where T : BaseEntity;
int Save<T>(T entity) where T : BaseEntity;
void DeleteSingle<T>(IQueryBase<T> query) where T : BaseEntity;
void DeleteList<T>(IQueryBase<T> query) where T : BaseEntity;
}
That way I can just inject a single repository into a class and use it to get whatever I need.
(by the way, I'm using Fluent NHibernate as my ORM, with a session-per-web-request pattern, and injecting my repository using Structuremap)
This seems to work for me - the methods I've defined on this repository do everything I need. But in all my web searching, I haven't found other people using this approach, which makes me think I'm missing something ... Is this going to cause me problems as I grow my application?
I read a lot of people talking about having a repository per root entity - but if I identify root entities with some interface and restrict the generic methods to only allow classes implementing that interface, then aren't I achieving the same thing?
thanks in advance for any offerings.
I'm currently using a mix of both generic repositories (IRepository<T>) and custom (ICustomRepository). I do not expose IQueryable or IQueryOver from my repositories though.
Also I am only using my repositories as a query interface. I do all of my saving, updating, deleting through the Session (unit of work) object that I'm injecting into my repository. This allows me to do transactions across different repositories.
I've found that I definitely cannot do everything from a generic repository but they are definitely useful in a number of cases.
To answer your question though I do not think it's a bad idea to have a single generic repository if you can get by with it. In my implementation this would not work but if it works for you then that's great. I think it comes down to what works best for you. I don't think you will ever find a solution out there that works perfectly for your situation. I've found hybrid solutions work best for me.
I've done something similar in my projects. One drawback is that you'll have to be careful you don't create a select n+1 bug. I got around it by passing a separate list of properties to eagerly fetch.
The main argument you'll hear against wrapping your ORM like this is that it's a leaky abstraction. You'll still have to code around some the "gotchas" like select n+1 and you don't get to take full advantage of things like NH's caching support (at least not without extra code).
Here's a good thread on the pros and cons of this approach on Ayende's blog. He's more or less opposed to the pattern, but there are a few counter arguments too.
I've implemented such kind of repository for NHibernate. You can see example here.
In that implementation you are able to do eager loading and fetching. The pitfall is that with NH you will often need to be able to use QueryOver or Criteria API to access data (unfortunately LINQ provider is still far from being perfect). And with such an abstraction it could be a problem leading to leaky abstraction.
I have actually moved away from repository pattern and creating a unit of work interfaces - I find it limiting.
Unless you anticipate a change in the datastore i.e. going from DB to textfile or XML - which has never been the case for me, you are best off using ISession. You are trying to abstract your data access and this is exactly what NHibernate does. Using repository limits really cool features like Fetch(), FetchMany() futures etc. ISession is your unit of work.
Embrace NHibernate and use the ISession directly!
I've used this approach successfully on a few projects. It gets burdensome passing in many IRepository<T> to my Service layers for each BaseEntity, but it works. One thing I would change is put the where T : on the interface rather than the methods
public interface IRepository<T> where T : BaseEntity
Now that I have a good handle on NHibernate 3.2 I now feel ready to use it in anger. What I need now is an ellegant way to inject the mappings I want from an IoC container like castle windsor or the like.
The project that I am working on requires 2 sets of mappings, one to a legacy database that needs to stay put for now and one to the new schema designed to replace the old database at some point in the future. Baring in mind that I am using mapping by code rather than xml mapping.
So at a controller/middle tier level you'd be injecting a repository that implements your ISomethingRepository interface and as a parameter into that repository somehow passing a collection of ClassMapping objects.
Any ideas about the best way to go about this would be appreciated. I'm interested in the general architecture which is why I'm not specifying an IoC container.
Why not have a SessionFactoryFactory which consumes a ConfigurationGenerator.
Using Fluent NHibernate, I have succeeded in setting up a global Filter on my NHibernate session, and using it in ClassMap classes. The Filter WHERE clause is appended to queries using that map automagically as it should - as described in other posts on this forum.
Fluent NHibernate does not implement ApplyFilter<> of SubclassMap, it is only implemented for ClassMap. It was easy to do a test by adding a filter through the back door, by passing a MappingProviderStore to the SubclassMap Constructor, and adding the filter to that. Inspecting the resulting classes in the debugger shows that everything is populated identically to a ClassMap. However, not surprisingly, this didn't work.
Can someone tell me if Filters SHOULD work with SubclassMap in NHibernate itself?
Is this therefore something that might eventually be supported (e.g. by implementing SubclassMap.ApplyFilter<>) in Fluent NHibernate?
Using Fluent NHibernate 2.1, with NHibernate 3.1
I'm supposing that fluent call apply filter the :
as per this Jira Entry, at Oct 2012 the function is not yet availavle in NH.
I see files like Castle.DynamicProxy.dll or Castle.Core.dll or Castle.Model.dll and various others similar in projects that are supposed to be simple, noob's introduction to nHibernate. What does this Castle stuff have to do with nHibernate? Is this unadvised muddying up the waters by the tutorial authors or does nHibernate really require this sort of extra hoops jumping just to get the basics running?
NHibernate uses proxy objects to achieve lazy loading and uses the Castle DynamicProxy module. This is the reason your entity properties need to be virtual. Because NHibernate creates proxy classes that intercept calls to your properties.
I'm looking for more information on the extension points within NHibernate.
For instance I know about IUserType and ICacheProvider. However I can't seem to find a good reference of all the different extension points that NHibernate provides?
Is anyone's Google-fu stronger than mine :)
There are no complete references on that... but it's not hard to look at the assembly and find the interfaces and base classes:
IInterceptor
IBatcherFactory
ICollectionTypeFactory
IProxyFactoryFactory
ICacheProvider
IConnectionProvider
ICurrentSessionContext
Dialect
IDriver
IIdentifierGenerator
ITuplizer
And many more...
Take a look at *EventListener (newer mechanism) and IInterceptor (older mechanism, but useful in certain scenarios that EventListeners don't cover). They will get you a long way WRT extending/integrating with NHibernate.
http://www.nhforge.org/doc/nh/en/index.html#events