A comparative analysis of Entity Framework and other ORM tools
Data access strategies have changed over the years. From Remote Data Objects (RDO), Data Access Objects (DAO), to ADO.NET, the industry has seen a marked improvement in the way data is accessed these days.
ORM tools enable you to access data from persistent storage devices without having to bother about how the underlying data is actually stored. NHibernate is a lightweight ORM tool for .NET. It has a statically compiled counterpart called Fluent NHibernate. Fluent NHibernate provides you with an XML-less, compile safe, automated NHibernate mapper with LINQ support. Domain modeling is an area where Entity Framework scores over NHibernate.
Consider the following entity class:
public class User { public virtual Int32 UserID { get; set; } public virtual String UserName { get; set; } public virtual String CreatedBy { get; set; } public virtual DateTime CreatedDate { get; set; } public virtual String ModifiedBy { get; set; } public virtual DateTime ModifiedDate { get; set; } }
Tip
Downloading the example code
You can download the example code files from your account at http://www.packtpub.com for all the Packt Publishing books you have purchased. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
The following class illustrates how you can create a mapping for the preceding class by extending the generic ClassMap<T>
class:
public class UserMap : ClassMap<User> { public UserMap() { Table("Users"); Id(x => x.UserID).GeneratedBy.Identity(); Map(x => x.UserName); Map(x => x.CreatedBy); Map(x => x.CreatedDate); Map(x => x.ModifiedBy); Map(x => x.ModifiedDate); } }
The following code example illustrates how you can create a data gateway for the User
entity class:
using FluentNHibernate; using NHibernate; using FluentNHibernate.Cfg.Db; using FluentNHibernate.Automapping; using NHibernate.Cfg; using NHibernate; using FluentNHibernate.Cfg.Db; using FluentNHibernate.Automapping; using NHibernate.Cfg; using NHibernate.Tool.hbm2ddl; using System.Reflection; namespace Packt { public static class DataManager { private static ISessionFactory sessionFactory = null; private static readonly string businessObjectsNamespace = "Packt.Entity.Mappings"; private static readonly string connectionString = @"Data Source=JOYDIP-PC\SQLServer2014; Initial Catalog=Security;Integrated Security=True"; private static ISessionFactory SessionFactory { get { if (_sessionFactory == null) { //Code to create a new session factory instance and load the business entities } return sessionFactory; } } public static ISession OpenSession() { return SessionFactory.OpenSession(); } } }
Note that you can make a call to DataManager.OpenSession()
to open the database connectivity session.
Entity Framework 6 is a mature ORM and comes up with many powerful features. When you use Entity Framework, you can concentrate more on writing application logic rather than writing the database connectivity code. This reduces development time and effort greatly.
Language Integrated Query (LINQ) is a query translation pipeline that you can use to integrate your queries into the object model. LINQ provides you with a framework that you can use to access relational data in a strongly typed way. LINQ provides a great way to query in-memory objects.
Here are the various forms that LINQ comes up with:
- LINQ to objects: This is used to query in-memory objects or a collection of in-memory objects
- LINQ to XML: This is used to query data retrieved from XML data sources
- LINQ to SQL: This is used to query data retrieved from SQL Server database
- LINQ to DataSet: This is used to query data from a DataSet or a DataTable
- LINQ to Entities: This is used to query data exposed by the EDM
The LINQ library contains two primary interfaces that all generic collection classes implement. These are the IEnumerable<T>
interface and the IQueryable<T>
interface. While the former exposes an enumerator to iterate over a collection of a given type T
, the latter provides a functionality to query a data source that will implement this interface. Also, IQueryable
allows you to filter data on the server side.
The following diagram illustrates how these interfaces are related:
LINQ to SQL and .dbml files
LINQ to SQL allows you create an object model that maps to the tables in the relational database. The object relational mapping implementation of LINQ to SQL handles the execution strategy of the SQL queries. A database markup language file, also known as .dbml
file, is generated by the Visual Studio IDE when you drag and drop database tables from the solution explorer onto the LINQ to SQL design surface. When each table is dragged on the design surface, a class is created for each table. These classes are known as entity classes
and they are partial classes.
Both LINQ to SQL and ORM share certain common behaviors in terms of designing, mapping entities with relational database, and querying entities.
Developing non-LINQ to SQL data-centric applications may consume a lot time and effort in trying to build custom components that will interact with the data source. LINQ to SQL maps tables to classes, which helps architects to design a better n-tier architecture, thus improving productivity.
The properties in the entity classes are mapped to the columns in the table with an appropriate data type mapping scheme. Hence, a compile time check is performed that reduces runtime errors.