Posts Tagged ‘Object Relational Mapper’
Entity Framework Vs NHibernate
I worked on EF POCO model for some times and I come across with several stopovers. EF doesn’t have a very good error reporting, it will just throw some error and we need to run pillar to post to find out why on earth we are getting this error. Another issue is working in disconnected mode, I will explain in detail later in this post. For testing I used EF CTP5, hopefully things might have improved in the latest release.
After dating with EF for quiet some time, I realized that EF is not matured enough to hang around with, it’s still evolving and need time. I thought I need to look around and see any other beautiful and healthy ORM’s around. Yes I do aware of NHibernate a powerful ORM in the market for quiet a long period. So I decided to see in depth. I decided to write a small app to compare both ORM’s. For my comparison I used FluentNHibernate, I like to map my entities to table using code rather than an xml.
I haven’t completed the comparison yet. One of the important focus of my test is how CRUD operation works in disconnected model. In connected model the context can keep track of the changes and do the necessary Create/Update/Delete operation without much issue. So my test app have a WCF service to supply data to presentation layer.
First Test
The presentation layer issue a search request and get an author object from the WCF service, make some changes to author data and send it back to service for persisting it.
Entity Framework: Presentation layer get author object, did some changes to First Name. Sent the modified object to Service for persisting. In the persistence layer attached the author object to ObjectContext and called SaveChanges(). But nothing happened, EF couldn’t recognize the changes made to the object and didn’t persist the changes.
NHibernate: Presentation layer get author object, did some changes to First Name. Sent the modified object to Service for persisting. In the persistence layer make a call to SaveOrUpdate() of Session object with the modified entity. I could see that the changes get persisted to the db.
Test Summary
In my first test I could see that update operation in disconnected mode is pretty easy in NHibernate than EF. I am not sure whether am doing some thing wrong in EF thus it’s not persisting. But from a devs stand point we really don’t want to do much stuffs with an ORM to persist any changes. It’s ORM’s headache to figure out whether the entity state is dirty or not, if dirty then update it.
After this small test I feel like I need to embrace NHibernate as my ORM. Also one of the good feature of NHibernate is it’s error reporting. NH will report error with sql statement it issued to db, it will be helpful for a dev to analyze the error and take necessary actions.
EF might be strong in Autogenerated code, with EDMX, blah, blah. But not yet matured enough to support POCO model. In my point of view NHibernate is the right ORM to choose in comparison with Entity Framework, if you are serious in POCO model.
Note: NHibernate uses lazy loading extensively and you may have some trouble in WCF side while serializing it. It’s advisable to use DTO to transfer data between layers. Trent Foley have a nice post to explain how to perform eager loading with NHibernate.
This is just an initial test and I will move forward to test different scenarios. If I get time I will post the results in future posts.
Overview of Test Application
The test application consist of Presention layer (Winform), WCF service, Domain model and Persistence layer. The service layer and the persistence layer is loosely coupled. At any point of time Service layer doesn’t know to whom he is interacting, it can be EF repository instance or NH instance, I achieved it by Caste Windsor IOC. This loosely coupled approach help me to compare both ORM without any single code change rather with a xml configuration change.
For the test app I used Pubs database. One of domain entity is shown below.
namespace ORM.Domain { [DataContract] public class Author { [DataMember] public virtual string Id { get; private set; } [DataMember] public virtual string LastName { get; set; } [DataMember] public virtual string FirstName { get; set; } [DataMember] public virtual string Phone { get; set; } [DataMember] public virtual string Address { get; set; } [DataMember] public virtual IList<Titles> TitlesAuthored { get; set; } public virtual bool Contract { get; set; } public Author() { this.TitlesAuthored = new List<Titles>(); } public virtual void AddTitles(Titles titles) { this.TitlesAuthored.Add(titles); titles.Authors.Add(this); } }
It’s just a anemic entity without much responsibility. Anyway my focus is not in DDD, so just bare with my entity structure.
Now I need to map my entity to Author table. I used fluent API’s of the ORM to do the mapping.
Entity Framework Mapping
public class AuthorConfiguration:EntityTypeConfiguration<Author> { public AuthorConfiguration() { HasKey(a => a.Id); HasMany(a => a.TitlesAuthored); Property(a => a.Id).HasColumnName("au_id"); Property(a => a.Address).HasColumnName("address"); Property(a => a.FirstName).HasColumnName("au_fname"); Property(a => a.LastName).HasColumnName("au_lname"); Property(a => a.Phone).HasColumnName("phone"); Property(a => a.Contract).HasColumnName("contract"); ToTable("dbo.authors"); } }
FluentHibernate Mapping
public class AuthorMap:ClassMap<Author> { public AuthorMap() { Id(x => x.Id,"au_id"); Map(x => x.LastName, "au_lname"); Map(x => x.FirstName, "au_fname"); Map(x => x.Address, "address"); Map(x => x.Phone, "phone"); Map(x => x.Contract, "contract"); HasManyToMany(t => t.TitlesAuthored).Cascade.All().Table("titleauthor")
.ChildKeyColumn("title_id")
.ParentKeyColumn("au_id");Table("dbo.authors"); } }
What ever I posted here is just my findings. Don’t consider this as a benchmark. You better consider your scenarios and do a small tracer and find out which suites your requirement. Pay careful attention before deciding on any ORM else you will suffer later.
I think it’s better to stop here, you all can look into my source code for more details. I uploaded my test application to Sky drive, if interested pls have a look at it.