I currently use nhibernate but a guy at work has recently gotten me interested in subsonic again. I really prefer a Poco, domain-driven style approach to development and worry about the database later. It looks like this is partially supported using simplerepository. My question is, how flexible is subsonic in how it generates your database ? For example, nhibernate supports all 3 different types of inheritance mappings and components. Components for those of you not familiar w/ NH, let you change how a class is stored in a table. So if you have a customer and address classes, in one situation you store the address in its own table and linked thru a foreign key, in another situation the address can be stored as part of the customer table.
Does subsonic give you these kind of options?
Thanks,
Craig
Does subsonic give you these kind of options?
In a word, no. SubSonic really doesn't have the flexibility of nhibernate, the payoff is that it also doesn't have the complexity or the rather brutal learning curve. If you really need the inheritance mapping flexibility of nhibernate then you won't get it with SubSonic. The only question then is whether you actually need it, I've found I can almost always do without it.
Related
Struggling between choosing linq2sql and nhibernate.
Let me give you some insight in the application in point form:
this is a asp.net mvc application
it will have lots of tables, maybe 50-60 (sql server 2008)
i would want all the basic crud logic done for me (which I think nhiberate + repository pattern can give me)
i don't have too complicated mappings, my tables will look something like:
User(userID, username)
UserProfile(userID, ...)
Content(contentID, title, body, date)
Content_User(contentID, userID)
So in general, I will have a PK table, then lots of other tables that reference that PK (i.e. FK tables).
I will also have lots of mapping tables, that will contain PK, FK pairs.
Entity wise, I want User.cs, UserProfile.cs and then a way to load each object.
I am not looking for a User class that has a UserProfile property, and a Content Collection property (there will be maybe 10-20 tables that will related to the user, I just like to keep things linear if that makes sense).
The one thing that makes me learn towards nhibernate is: cross db potential, and the repository pattern that will give me basic db operations accross all my main tables almost instantly!
Since you seem to have a quite straight forward mapping from class to table in mind Linq to SQL should do the trick, without any difficulties. That would let you get started very quickly, without the initial work of mapping the domain manually to the database.
An alternative could be using NHibernate + Fluent NHibernate and its AutoMapping feature, but keep in mind that the Fluent NHibernate AutoMapping is still quite young.
I'm not quite sure I understand what you want your entities to look like, but with Linq to SQL you will get a big generated mess, which you then could extend by using partial classes. NHibernate lets you design you classes however you want and doesn't generate anything for you out of the box. You could kind of use POCO classes with Linq to SQL but that would take away all the benefits of using Linq to SQL rather than NHibernate.
Concerning the repository pattern, and the use of a generic repository, that can be done quite nicely with Linq to SQL as well, and not only with NHibernate. In my opinion that is one of the nice things about Linq to SQL.
If you probably will need support for other databases than SQL Server, NHibernate is the only choice. However, if it probably won't be an issue I would recommend not using that as the primary factor when choosing. The other factors will probably influence your project more.
Conclusion:
All in all, I would recomment Linq to SQL, in this case, since it would let you get started quickly and is sufficient for your needs. The precondition for that is that you don't have a problem with the thought of having generated, messy code in your domain, and that you are quite sure there will not be any need to support other databases in the future. Otherwise I would recommend NHibernate, since it is truly an awesome ORM.
linq2sql really wants you to work with 1 table per class mapping. So if you have a UserMaster and a UserDetail table, you are looking at two objects when using default linq object generation. You can get around that by mapping linq entities to business entities (see Rob Conery's storefront screencasts), but then you are back to writing object mapping code or using something like Automapper.
If you want to be able to split your classes across multiple tables, then I'd say go with NHibernate. If not, then linq has a lower learning curve.
The only way I'd ever use nHibernate in through Castle Project's ActiveRecord library. Otherwise, nHibernate becomes its own little infrastructure project. Check out some questions in the nHibernate tag to see what I'm talking about.
The only thing I might change about AR is to return results of SELECT operations as List instead of T[]. Of course, with the source code in C# I can do that if I want.
With ActiveRecord, the mapping information is saved in attributes you decorate your classes with. It's genius and I am a huge proponent of the pattern and this particular library.
So I'm having a head against the wall moment and hoping somebody can come help either remove the wall or stop my head from moving!!
Over the last 3/4 weeks I've been investigating ORM's in readyness for a new project. The ORM must map to an existing, large and ageing SQL database.
So I tried Subsonic. I really liked v2 and v3 after modding to work nicely with VB and named schemas in SQL was running OK. However, its lack of flexibility of having separate entity properties names vs column names had me pulling my hair out (sorry Rob).
I tried Entity Framework but I found like others it lacking in certain areas.
So I bit the bullet and tried nHibernate but after a week or so getting it working how I liked (with help from Codesmith to generate classes/hbms for me) I'm frustrated with the time it takes to startup (build a config object), despite trying a number of tricks to reduce this time.
I'm essentially after building a DAL class that I can share between apps and websites. Am I barking up the wrong tree? For a legacy project with 100s of tables should I go back to ado.net and use DTOs? Aarrgh!
Sorry for the ranty style of question. I don't have much hair left and I'd like to keep what I have!!
Thanks in advance, Ed
PS. I should add that I know SQL very well and not scared of getting my hands dirty to write fast queries. If anything I don't need to be hid from SQL
ORM let's you:
To map table rows to objects, that are the the workable pieces of object oriented programming.
To automatically navigate through object relationships
To easily add, edit and remove table rows
To query the database in a more intuitive way as you don't have to think of joins (this one will depend on the ORM and the query method)
To transparently handle L1 and L2 cache.
All of the above would have to be handled by hand if you werent using ORM.
PS: I agree to Dmitry as to the startup time of NHibernate (see question comments). Besides, did you try Fluent NHibernate? Fluent NHibernate is impressively easy. I couldn't believe my eyes when I first mapped a database. It's even easier than proprietary ORMs like DevExpress XPO.
The biggest benefit of an ORM tool is that it will help you layer your application correctly. Most project nowadays use a Data Layer to connect to the database. You start from the ORM tool to produce classes that correspond to your database objects. Then you define an interface using these methods. All persistence code uses the methods of this interface. This way the business logic layer is only coupled to this higher-layer interface and needs to know nothing about the database. In fact there should be no dependency on ADO.NET or even NHibernate.
Another advantage of ORM tools is that you de-couple your application from the database server. You could change the db engine and still use the same code. Also there isn't only the complexity of the SQL that the ORM hides from you. It can also help you with transactions logic and connection pooling.
I'd say that for new projects an ORM tool is a necessity. For legacy projects it isn't so much beneficial, unless of course you have the time/money to start from scratch.
In my experience, most ORMs end up being way more complex than SQL. Which defeats the entire purpose of using them.
One solution I'm enthusiastic about is LINQ2SQL. It excels as a thin layer about stored procedures or views. It's really easy to use and doesn't try to hide SQL.
There are basically two questions here:
What's great about ORMs? There are similar questions on Stackoverflow. See:
What are the advantages of using an ORM?
Is everyone here jumping on the ORM band wagon?
How can I improve NHibernate startup time? See:
http://ayende.com/Blog/archive/2007/10/26/Real-World-NHibernate-Reducing-startup-times-for-large-amount-of.aspx
http://nhforge.org/blogs/nhibernate/archive/2009/03/13/an-improvement-on-sessionfactory-initialization.aspx
I am looking for some up to date information comparing NHibernate and iBATIS.NET. I found some information searching Google, but a good bit of it applies either to the Java versions of these products or is dated.
Some specific things I am interested in:
Which is better if you control both the data model and the application?
iBATIS is repeatedly called simpler to learn - does this have long-term maintenance consequences (i.e. easy to start, hard to maintain)?
Do both make it easy to switch the underlying database vendor?
How skilled do your developers need to be with SQL?
Any major feature that one has that the other lacks?
Is either product more suitable for a particular type of application?
Real world examples of observed benefits and drawbacks are appreciated!
EDIT: Thanks for the information. I am doing my own evaluation as well. One thing I am wondering about still, does iBATIS help you to save/update complex object graphs? It seems like NHibernate is nice in that I can pass it a root object and it figures out the details of what, if anything, needs to be updated in the database.
I made some research a while ago.
One specific question from me, might give you some additional information:
Would you use NHibernate for a project with a legacy database, which is partly out of your control?
Some of your points of interest I can answer:
Which is better if you control both the data model and the application?
I can answer it the other way around: If you don't have control over the data model and thus facing some legacy database, iBatis is the better choice.
iBATIS is repeatedly called simpler to learn - does this have long-term maintenance consequences (i.e. easy to start, hard to maintain)?
It depends what you want to do with it. If you have a domain driven development approach then iBatis might get painful by time. If you just do simple data manipulation and don't have a full blown domain model then nHibernate might be a overkill by the time.
Do both make it easy to switch the underlying database vendor?
Both have mechanisms to shield you off from a specific database vendor, but I admit that have not done intense research in this direction.
How skilled do your developers need to be with SQL?
When you use iBatis, you need more SQL skills than NHibernate. Using iBatis you always need to code some SQL. NHibernate doesn't require you to code SQL statements -- it even can do the DDLs for you. Powerful features will require you to go to old good SQL, which will be inevitable.
Some other points:
I personally find that iBatis much more lightweighter. You can get things done very quickly. NHibernate is more powerful, but has much more features, which you can use in wrong way.
It is possible to combine the use of NHibernate and iBatis! You can use NHibernate for your business logic. For reporting purposes, where you just read data out of tables, fallback to iBatis.
If your application has a longer life cycle and a lot of business logic, consider NHibernate. It has a lot of feature aiding you in handle business objects.
The community around NHibernate is very active and come up with useful tools.
In a sense it's comparing apples to oranges.
Which is better if you control both the data model and the application?
They both work with normalized databases well, so they are more-or-less equal if you can shape the db. iBatis is better at mapping to legacy databases since it doesn't actually care about the database structure at all. It only cares about the shape of the result set.
.iBATIS is repeatedly called simpler to learn - does this have long-term maintenance consequences (i.e. easy to start, hard to maintain)?
It is much simpler, but that is because it has a much smaller featureset. I don't think it has any ticking timebomb long term maintenance issues.
Do both make it easy to switch the underlying database vendor?
Yes
How skilled do your developers need to be with SQL?
Both require a good knowledge of SQL. With iBatis, you still have to write the sql queries/procs. With NHibernate you have to know how to write NHibernate queries to get effective SQL. Neither are a replacement for SQL knowledge.
Any major feature that one has that the other lacks?
iBatis is a datamapper (a term used on the iBatis site). NHibernate is a full-blown Object Relational Mapper. iBatis is a great way to go if you primarily want something that takes the monotony out of mapping objects to result sets. However, it doesn't go all the way in trying to solve the object/relational mismatch. NHibernate has many more features such as dirty tracking, caching based on identity /identity map, flexible querying, dynamic sql, batching etc... NHibernate is much more dynamic in that it can do many things in one trip to the DB that could take iBatis several trips.
We recently posted an article comparing these two tools, and I think many of your questions are addressed. The article is here on our wiki site.
For me the answer is currently: No, I would use iBatis, because NHibernate is a pain, when the database model and the object model are not in synch. If I don't have full control over the database I end up with a lot of work.
Why do I ask?
Well, first of all: I never used NHibernate. I just know it from the surface. I have read about the advantages of iBatis for legacy databases.
Second: Recently I had a discussion with someone who worked with Hibernate (jep, without 'N' before Hibernate). He told me that the ORM frameworks are now pretty advanced and advocated Hibernate. Since I was not interested in NHibernate, I didn't keep track of the recent developments.
Maybe I its time to rethink my answer, or not?
iBatis is certainly easy to map objects to legacy database systems.
More recently NHibernate 1.2 and 2.0 have a feature set that may make you rethink iBatis.
NHibernate works with composite keys, which can occur frequently in older databases, they aren't always pleasant to work with but support is there for this.
NHibernate can utilise Stored Procedures for CRUD operations on entities, also database views.
Collections can be custom stored procedures or SQL queries. Collections can use the property-ref attribute when the Foreign Key relationship doesn't map directly to the Primary Key on the other side.
Some of these features may take away from the performance/power of nhibernate, ie Lazy Loading with property-ref doesn't work (at all?), but is most cases there are reasons for this.
Other points: (which aren't really related to your legacy database but still can help decide on a technology choice)
The Nhibernate community appears much richer than the iBatis. I'm on both lists and the volume of support for NHibernate is quite large compared to the iBatis group. So support should be easier.
Also there is a growing amount of contrib/3rd party tools for NHibernate. Things like The NHibernate Profiler, the Nhibernate Query Analyzer, NHibernate Contrib, Fluent NHibernate to name a few.
Perhaps you can expand on what advantages you believe iBatis currently has. NHibernate has certainly been quite active recently and has gained many new features, a lot of which do assist in legacy/hard to modify schemas.
And to answer the question, yes we do use NHibernate with legacy databases that have awful relationships, composite keys, broken relationships. We still also have a small amount of code based on iBatis. We no longer write any more iBatis code though.
Yes, consider NHibernate. It's the gold standard for a reason. I have heard that iBATIS supports crazy mapping possibilities, but with NHibernate's IUserType you can map anything, even really strange columns.
#Ahmad, the entire point of ORM is to prevent a tight coupling between your objects and your schema. If you have this problem you're doing it wrong.
Also, with NHibernate there are plenty of options for custom queries, formula properties and stored procedures. HQL is extremely powerful and Criteria is flexible.
I think you'll be doing your clients a disservice if you don't at least spike NHibernate.
I've been using nHibernate in an existing application. I use it for all new development, I have no intention of porting the existing stuff over either there just isn't a compelling reason but for new stuff on the project it works great.
If you are going to port the code over then you should be able to change the database to match better with your domain model, without much impact (depending on how leaky your database is ie who access it). Changing the domain model would impact the application however.
I find I can do more with NHibernate, and even Castle than with the Linq to Entities, or linq to SQL.
Am I crazy?
No you're not crazy. nHibernate is a full OR Mapper, Linq to SQL and Linq to Entities don't implement everything you'd expect from an OR mapper and targeted at a slightly different group of developers.
But don't let that put you off linq though. Linq is still a pretty good idea.. Try Linq to nHibernate :-)
The big drawbacks to NHibernate, Castle, etc., is that they're not exactly light-weight (especially NHibernate.)
Linq to SQL is good for a light-weight, limited use ORM.
I've used both NHibernate and LINQ to SQL. From my point of view it depends on the project, if I need something quick, I would choose L2S, it's so simple to create the dbml mapping and start using it. If I'm developing a more highlevel enterprise solution I would go for the tried and trusted ORM - NHibernate, I find the logging & transaction features simple to use.
LINQ to SQL has a relatively short learning curve, NHibernate has a much steeper learning curve.
LINQ to SQL only supports SQL Server, so if you've an Oracle database then the decision is already made - NHibernate.
I'd recommend checking out http://www.summerofnhibernate.com/ for excellent screencasts on learning NHibernate.
One thing to bear in mind is that NHibernate can be an absolute pig to configure - especially since its based mainly on XML config files because of its roots as the original Hibernate.
Fluent NHibernate goes some way to making this less painful.
Linq certainly though fits in with the general 'way' in which .NET works.
Blockquote Linq certainly though fits in with the general 'way' in which .NET works
Yikes, this kind of sentiment scares me. The RAD stuff built into .net is NOT how dot net works, it's just a tool set for getting prototypes up. .NET allows us to do full DDD applications, w/ high levels of cohesion, seperations of concerns, and allows us to write decoupled code, despite all the attemps ms makes to couple things. I would strongly disagree that .net likes to be coupled, certian tools like to be coupled, i'll include linq to sql in this fray. linq to sql destroys the idea of having a seperate domain model. I cringe at the thought of using my database schema as the underlying model objects. Proper ORM tools should allow us to model our domain first, then link our relational database to these models. NOT the other way around.
I have not tried the Entity Framework, but I definitely would recommend NHibernate over Linq to SQL; The biggest reason I can give is just the control. Linq to SQL likes to have a lot more control over everything, loading the object and maintaining all kinds of tracking information about the object. If you serialize/deserialize, the tracking information can be lost and strange things can happen when saving it again. NHibernate works more as a repository should - You hand it whatever object you want (that you have configured it to understand, of course), and it puts it away in the database, regardless of what you've done with it.