
Whilst preparing for my Entity Framework 4.0 and Unit Testing presentation at the recent New England Code Camp, I came across an issue with my code that I couldn’t entirely understand. Picture the scenario:
In Visual Studio 2008 utilizing EF 1.0:
- Create a repository Assembly that contains the model and entity classes (i.e. no POCO) for a group of tables in my DB
- Create a Manager class to expose public functions / methods to retrieve data from the DB via the EntityContext
[store the Manager.cs file in a common area and create a Link to it from the project]. - Create an extension method that will handle the usage of Lambda expressions inside the context of .Include() [Did I say I hate "magic strings"?]
[store the ObjectQueryExtension.cs file in a common area and create a Link to it from the project] - Create a simple Console app to call the methods on the Manager class
[store the Program.cs file in a common area and create a Link to it from the project].

In Visual Studio 2010 Beta 2 utilizing EF 4.0:
- Create a repository Assembly that contains the model and entity classes (i.e. no POCO) for a group of tables in my DB
- Create a Manager class to expose public functions / methods to retrieve data from the DB via the EntityContext
[create a Link to the Manager.cs file from the project in a common area]. - Create an extension method that will handle the usage of Lambda expressions inside the context of .Include()
[create a Link to the ObjectQueryExtension.cs file in the common area from the project] - Create a simple Console app to call the methods on the Manager class
[create a Link to the Program.cs file in the common area from the project].

As you will see, the only difference between the two solutions is the actual EntityFramework context definition; one utilizes EF 1.0 and the other EF 4.0.
Compile and execute both and it works perfectly, same Program.cs code for both (making the Console Application); same Manager.cs and ObjectQueryExtension.cs code for both (making the RepositoryManager assembly).
Now the fun starts. I then worked my way back to using Dependency Injection and created the unit test methods based on the VS 2010 project described above. When the compiler attempts to compile the following section of code:
IQueryable<Person> query = context.PersonSet
.Include(p => p.PersonalDetail)
.Include("FavoriteBeers.Beer")
.Include(p => p.Customer.Include<Customer, CustomerType>(c => c.CustomerType))
.Include(p => p.Addresses);
The following compile error was the result of the attempted compilation against the preceding code:
Ef4.0AndEf1.0\PocoInEF4.0\EFWorkshop.Poco.RepositoryManager\Manager.cs(78,53): error CS1660: Cannot convert lambda expression to type 'string' because it is not a delegate type Ef4.0AndEf1.0\PocoInEF4.0\EFWorkshop.Poco.RepositoryManager\Manager.cs(78,58): error CS0311: The type 'EFWorkshop.Poco.Base.Entities.Customer' cannot be used as type parameter 'TSource' in the generic type or method 'EFWorkshop.Ef.Repository.ObjectQueryExtension.Include<TSource,TPropType>(TSource, System.Linq.Expressions.Expression<System.Func<TSource,TPropType>>)'. There is no implicit reference conversion from 'EFWorkshop.Poco.Base.Entities.Customer' to 'System.Data.Objects.DataClasses.IEntityWithRelationships'. Ef4.0AndEf1.0\Common\ObjectQueryExtension.cs(118,33): (Related location) Ef4.0AndEf1.0\PocoInEF4.0\EFWorkshop.Poco.RepositoryManager\Manager.cs(78,60): error CS1061: 'System.Linq.IQueryable<EFWorkshop.Poco.Base.Entities.Person>' does not contain a definition for 'Customer' and no extension method 'Customer' accepting a first argument of type 'System.Linq.IQueryable<EFWorkshop.Poco.Base.Entities.Person>' could be found (are you missing a using directive or an assembly reference?)
However, the following “magic string” laden Includes compile and execute fine:
IQueryable<Person> query = _context.People
.Include("FavoriteBeers.Beer")
.Include("PersonalDetail")
.Include("Customer.CustomerType")
.Include("Addresses");
Therefore it would seem that the non POCO based classes permit us having the Lambda expression based includes as described earlier; however the moment that POCO is introduced that style of Include is no longer viable – or is it?

Tomas says:
Your ending question implies you might have a solution to this problem. Do you? If so, where can I find it? =)
April 9, 2010, 17:08