I have an old outdated application written using NHibernate. Now I would like to rewrite it including new functionality and big changes in model.
What are main disadvantages of using Linq to SQL instead of NHibernate ?
What are possible problems of using LINQ to SQL, does making DataCont开发者_运维问答ext as something like singleton can give poor performance?
From "The false myth of encapsulating data access in the DAL":
"I would like to design a system/application using NHibernate. But I also want to so flexible that in future ,if I unplug the NHibernate and use ADO.NET Entity framework or other framework then my application should not crash."
In short, I am completely opposed for even trying doing something like that.
It is based on flawed assumptions
A lot of the drive behind this is based on the historical drive built in the time where data access layers directly accessed a database using its own dialect, resulting in the need to create just such an encapsulation in order to support multiple databases.
The issue with this drive is that it is no longer a factor, all modern OR/Ms can handle multiple databases effectively. Moreover, modern OR/M are no longer just ways to execute some SQL and get a result back, which is how old style DAL were written. An OR/M takes on a lot more responsibilities, from things like change tracking to cache management, from ensuring optimistic concurrency to managing optimal communication with the database.
And those features matter, a lot. Not only that, but they are different between each OR/M.
It doesn’t work, and you’ll find that out too late
The main problem is that no matter how hard you try, there are going to be subtle and not so subtle differences between different OR/Ms, those changes can drastically affect how you build your application.
So how do you move between OR/Ms?
There are reasons why some people want to move from one data access technology to the other. I was involved in several such efforts, and the approach that we used in each of those cases was porting, rather than trying to drop a new IDataAccess implementation.
Huge question but one thing that I was made aware of during a large refactor from L2S to NHibernate 2.x is that NHibernate allows for a base class to be represented in a different physical table than the derivative. But with L2S I was forced to use 1 single table to represent the base and each class that would extend it.
This allowed me to create smaller tables because I had a base class that was inherited by about 25 different variations of child classes. If you would like to use this functionality going forward it could help simplify your schema.
What are main dissadvantages of using Linq to SQL instead of NHibernate ?
Advantages of LINQ to SQL
- More advanced and easier to use (IMHO) querying syntax, specifically it uses LINQ to perform queries, which give you strongly typed/compile time safe queries. NHibernate gives you HQL, which although quite powerful, is all string based. NHibernate also has Criteria queries which a bit more strongly typed (still some strings), but it's syntax/API is quite difficult to get one's head around.
NHibernate v2 does have a LINQ provider you can download, but it's a bit lacking (a lot lacking in fact), plenty of use cases it doesn't support. NHibernate 3.0 comes with it's own built in LINQ provider which is much more powerful, almost up to par with LINQ 2 SQL or EF.
Disadvantages with LINQ to SQL
Just about EVERYTHING else! Seriously where do I start:
Simple Table to entity mapping , unlike NHibernate which has more powerful mapping capabilities including: Unidirectional associations, component mapping, you can map collections of value types such as
public IList<string> Tags {get; set; }
, inheritance mapping (very powerful), Enum mapping, plus more...Your entities become tightly coupled to LINQ to SQL, which can effect unit testing. NHibernate supports POCO mapping, important for implementing loosely coupled, maintainable, unit testable code base.
Supports more databases (SQL Server, MySql, PostgreSQL, Oracle, SQLite, + more). LINQ 2 SQL only supports MS SQL Server.
Ability to implement DDD (Domain Driven Design) principles in your application with NHibernate. LINQ 2 SQL is more of a database centric view of your domain model, whereas NHibernate takes a more business/behaviour centric view of your domain.
Seriously, taking an NHibernate application and 'downgrading' it to LINQ 2 SQL seems like a step backwards. If you want to use something more Microsofty at least consider using Entity Framework 4.0. LINQ 2 SQL has it's place with simpler applications with only a few tables, but anything more complicated needs a more powerful ORM.
When I'm building an app, and it has a simple domain, and a basic schema, I love Linq2Sql. Linq is quick to write, and I can get things done quickly. I realize there is a Linq2NHibernate out there, but I'm not sure what the maturity of it is. Some downsides, IMO to Linq2Sql are having to regenerate classes and the DataContext whenever the schema changes, and having to map from Linq2Sql generated classes, into my domain objects. For small easy projects, I really don't mind doing this. Though with FluentNHibernate, and Linq2NHibernate, I might be able to be just as efficient with NHibernate as with Linq2Sql, but I haven't tried.
I was on a project that was using Linq2Sql on an over-normalized database with a somewhat complex domain, and it was a nightmare. It worked, and we were able to wrestle some good performance out of it, but the maintainability was almost non-existent. But with the schema the way it was, I'm not sure NHibernate, or straight SQL would have changed that. This is one case where without a doubt in my mind, a Document Database would have been the way to go.
If the project was already done with NHibernate, and you have that experience, I would stick with it. The fact that you can map directly to your domain objects is great. Linq2Sql code generation can be a pain when the schema is changing early in development. On top of that, Linq2Sql is effectively dead. MS is putting all of its ORM eggs in the Entity Framework basket.
Rather than doing a full port, maybe all you need is to LINQ-ify your NHibernate layer...
http://www.hookedonlinq.com/LINQToNHibernate.ashx
Some additional reading material:
http://www.caffeinatedcoder.com/linq-to-nhibernate/
Quote:
Thanks to the new NHibernate LINQ provider, I can now work in a mode that is not only more type safe, but also much more readable.
Look at these before and after queries and judge for yourself:
Before (Criterion API)
1: public IList<Call> GetCallsByDate(DateTime beginDate, int interpreterId)
2: {
3: ICriteria criteria = Session.CreateCriteria(typeof(Call))
4: .CreateAlias("Customer", "Customer")
5: .Add(Restrictions.Gt("StartTime", beginDate))
6: .Add(
7: Restrictions.Or(
8: Restrictions.Lt("EndTime", DateTime.Now), Restrictions.IsNull("EndTime")
9: )
10: )
11: .Add(Restrictions.Eq("Interpreter.Id", interpreterId))
12: .AddOrder(Order.Desc("StartTime"))
13: .AddOrder(Order.Desc("Customer.Name"));
14:
15: return criteria.List<Call>() as List<Call>;
16: }
After (LINQ to NHibernate)
1: public IList<Call> GetCallsByDateWithLinq(DateTime beginDate, int interpreterId)
2: {
3: var query = from call in Session.Linq<Call>()
4: where call.StartTime > beginDate
5: && (call.EndTime == null || call.EndTime < DateTime.Now )
6: && call.Interpreter.Id == interpreterId
7: orderby call.StartTime descending, call.Customer.Name
8: select call;
9:
10: return query.ToList();
11: }
if i remember correctly Linq2Sql does not support Many to Many table relationships nicely
http://www.chrisbrandsma.com/2007/08/linq-to-sql-many-to-many-tables-and.html
精彩评论