Click here to Skip to main content
15,867,568 members
Articles / Programming Languages / C#
Article

LINQ in Multi-tier Applications

Rate me:
Please Sign up or sign in to vote.
4.17/5 (15 votes)
24 Apr 2008CPOL6 min read 61.6K   399   60   14
Transfer data between LINQ entity classes and your own data transfer objects efficiently

Introduction

If you had the chance to work with LINQ, the latest Object Relational Mapping tool (ORM) added to the .NET 3.5 platform, then you understand how LINQ maps your database structure into several classes in your application. It creates for each table an entity class that has its properties mapped to the columns of the table in context. The whole point of ORM tools is to bring the database structure up to the language’s level so that your code would be aware of the structure at compile time. Nowadays developers tend to divide their application’s architecture into several distinct layers, usually 3 layers:

  1. Physical layer which encapsulates code that accesses your database one way or another
  2. Business layer which usually has your business logic code
  3. User interface layer which is usually a desktop .NET application or an ASP.NET application

I am not going to go into the details of the benefits of dividing your design into multi layers, nor discuss the pros and cons of LINQ itself, there are a lot of article on the Internet on this subject.

When you use LINQ in your physical layer to access the database, LINQ creates entity objects. A quick example will explain this. If you have a table called Accounts then LINQ creates a class called Account that has its properties set similar to the columns in the database. Now if you use this class itself to transfer the data to the upper layers (specifically all the way to the presentation layer) then you would realize that your application will cease to be multi-tier in dependencies. Your presentation layer will “see” entity classes that are created by the physical layer and this is bad because your layers are no longer loosely coupled as one would hope, but they are tightly integrated with each other.

To keep the spirit of multi-tier architecture, developers usually create a set of parallel classes that map the entity classes, by doing this, we add a layer of abstraction necessary to keep things clean between the dependencies between layers. This way, the presentation layer would only depend on the business layer and no longer on any layer below that.

Usually there are two approaches to these intermediate classes, also known as data transfer objects, dtos. Somewhere along your code, you will need to transfer the data between the entity objects and between your data transfer objects. So how do we do this? Some choose to code this part manually which is good, performance wise, but big trouble when it comes to maintaining these classes, not to mention all the amount of wasted human energy in donkey work. Some choose to benefit from the powerful features of reflection and write some code to copy the objects at runtime based on their properties, this is usually the preferred approach. The properties of the objects are discovered at runtime using Reflection, and copied to each other. This method has the big advantage that you do not need to write code for each pair of classes to copy properties from the entity classes to the data transfer objects, this saves you a lot of maintenance and a lot of time. Unfortunately this method suffers from low performance as reflection is slow, and you will not know how low the performance is until you really test it.

The Solution, A Better Approach

What if you can take the advantages of these two methods and none of their disadvantages? What if you choose to go with the first approach, where you write code for each and every pair of classes to copy their properties but instead of writing them yourself, you would have a developer working for you at runtime and writing this code for you very quickly and best of all, he works for free. This programmer is Mr. Emit.

Mr. Emit or his full name is System.Reflection.Emit will use Reflection at runtime to discover the two objects, the entity and the dto and then write code for you once that you can use at runtime to copy the properties efficiently between the two objects. Reflection.Emit is the namespace that allows you to create code at runtime using IL language, the intermediate language of the .NET platform.

Using the Code

Using this code is very simple, just add it to your solution or add a reference to its DLL. And whenever you have two objects to copy, just pass them to the static function DynamicFiller.FillObject(…) or use DynamicFiller.FillArray if your input is an array of objects and not just one object. There is a method in this class called AllowedType. This method has the types of properties that this class is allowed to copy, you can add to it whenever you have some types of properties that are not handled.

Performance Benefits

Before I wrote this code, I had code that used reflection. Using reflection, copying 10,000 objects (with around 15 properties for the object’s class) took around 32 seconds on a 1.8 Mhz Core 2 Duo Centrino CPU with 2 GB of RAM Laptop (non debug), in debug mode it took 1 minute, 19 seconds. Doing the same operation using the new Emit code took 19 milliseconds in non debug and 22 milliseconds in debug mode. Yes that is correct, milliseconds. The numbers speak for themselves.

A Look Under the Hood

Explaining how to write IL (Intermediate Language) code is beyond the scope of this article, however I will try to give you a head start if you are interested in understanding what the code does and how it does it. The code creates classes at runtime that implement the interface IDynamicFiller. The IDynamicFiller has just one method that is called FillObject and takes two objects of type Object that the class should copy. When these classes are coded at runtime, they are given a composite name that depends on the type of objects passed in and they are added to a Dictionary, this way the same class will be retrieved the next time it is needed to copy data between the same two types of objects. The created classes implement the interface IDynamicFiller by creating a new method class FillObject and inside this method the two passed objects are casted to their proper types and then properties are copied from one object to the other.

Conclusion

System.Reflection.Emit is an underused namespace due to the fact that you would need to know IL to use it. However it is not that hard, if you give it sometime the rewards are worth your while. A lot of solutions developed using the Reflection namespace can be made much faster using Emit namespace. And this is a very good example. Happy coding.

History

  • 25th April, 2008: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead
Lebanon Lebanon
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralDatabinding Pin
DotNetWise10-Nov-08 6:01
DotNetWise10-Nov-08 6:01 
GeneralRe: Databinding Pin
Ralph Varjabedian10-Nov-08 21:55
Ralph Varjabedian10-Nov-08 21:55 
Interesting, Are you referring to Eval in the DataBinding context? or in other uses?
Thanks.

Ralph Varjabedian
Chief Software specialist

My Blog
Bytesurge.com



GeneralRe: Databinding Pin
Ralph Varjabedian10-Nov-08 23:47
Ralph Varjabedian10-Nov-08 23:47 
GeneralRead Only / Write Only Properties Pin
ptyork27-Apr-08 23:04
ptyork27-Apr-08 23:04 
GeneralRe: Read Only / Write Only Properties Pin
Ralph Varjabedian28-Apr-08 0:17
Ralph Varjabedian28-Apr-08 0:17 
GeneralRe: Read Only / Write Only Properties Pin
Ralph Varjabedian28-Apr-08 0:30
Ralph Varjabedian28-Apr-08 0:30 
GeneralRe: Read Only / Write Only Properties Pin
ptyork28-Apr-08 16:32
ptyork28-Apr-08 16:32 
GeneralRe: Read Only / Write Only Properties Pin
Ralph Varjabedian29-Apr-08 12:35
Ralph Varjabedian29-Apr-08 12:35 
Generalplease add complete Multi-tier example Pin
Thanks for all the fish25-Apr-08 8:22
Thanks for all the fish25-Apr-08 8:22 
GeneralRe: please add complete Multi-tier example Pin
Ralph Varjabedian26-Apr-08 10:05
Ralph Varjabedian26-Apr-08 10:05 
GeneralRe: please add complete Multi-tier example Pin
ElleryFamilia9-May-08 8:44
ElleryFamilia9-May-08 8:44 
GeneralRe: please add complete Multi-tier example Pin
Ralph Varjabedian9-May-08 9:15
Ralph Varjabedian9-May-08 9:15 
GeneralNice article Pin
amplifity25-Apr-08 3:25
amplifity25-Apr-08 3:25 
GeneralRe: Nice article Pin
Ralph Varjabedian26-Apr-08 10:04
Ralph Varjabedian26-Apr-08 10:04 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.