An interesting migration problem from "Linq to Sql" to "Linq to Entities"

September 15, 2008 07:09 by ndibek

As you might have seen  from few of my previous posts I have been working on the MVC demo implementing Csla.  DAL layer of that demo used the Repository pattern, which is essentially just a wrapper around Linq2Sql DataContext:   

 
Then we would have one implementation of IRepository for each Linq to Sql table / DTO object, like for example SqlCustomerRepository.GetAll(), SqlOrdersRepository.GetAll(), etc.
 
All that each of the GetAll() methods would do is return (this is the implementation in SqlCustomerRepository):
 
 
where _db is an instance of the Linq DataContext.  Hiding DataContext away from our BO and abstracting it away from business layer objects makes it easier to test our business objects.  It makes it easy to replace the SqlCustomerRepository, with TestCustomerRepository that might return hard-coded list of Customers instead.
 
Then we use this inside our business object applying necessary filters - all that the method returns is IQueryable<T> so it makes it easy to use result of GetAll() in another Linq query:
  
 
One problem Rocky noticed in this design is that we are returning Linq generated DTOs.  What if our application needs to migrate to Oracle as a back end, for example.  The only option then is Linq to Entities.  But the type generated by Linq to Entities is different than type generated by Linq to Sql.  Although they might have similar signatures they are different objects.
 
One solution would be t create generic Data Transfer Objects that are neither  Linq to Sql neither Linq to Entities and then "map" the either implementations to these "shared" objects that are instead sent as DTOs.  Problem - one would have to hand code all that stuff.  
 
So for now I decided to give up on Linq to Sql in my demo and migrate it to Linq to entities.  Having 2 different database back ends would not matter in Entity Framework as either Sql Server or Oracle tables are mapped into Entities.  But that meant migrating to Linq to Entities.
 
I thought that this will present not much work at all as the queries are rather simple, and both frameworks support the same Linq syntax.  So I regenerated my Entity diagram using EF.  Everything compiled - good!.  
 
But when I ran the application - I got the following error:
 
Only parameterless constructors and initializers are supported by LINQ to Entities.
 
So although it compiled as perfectly valid Linq Query, at runtime it broke due to the fact that Linq to Entities can not evaluate expression if there are constructors with parameters, or initializers that are not an anonymous objects.  Took me a while to wrapmy head around that statement, but that essentially is what EF team states.  You can check it out in greater detail on following two sites:
 
Essentially Linq2Entities was complaining about:
 
select new OrderInfo(order)
 
part.   OrderInfo is the BO that is part of the list I am trying to populate from EF Entity - order, which is passed as a parameter to its constructor.  So essentially I had to modify the Fetch() method to following:
 
 
 
So what changed?  We are selecting the "order", which is the Linq to Entities object, and then we have to iterate through the list of those objects to map one at the time (as can be seen from use of Add() method instead of AddRange() which was used in Linq to Sql version).
 
Yet another "feature" that any of us migrating from Linq to Sql to Linq to Entities should be aware of.
  
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Comments

Add comment


(Will show your Gravatar icon)  

  Country flag

biuquote
  • Comment
  • Preview
Loading