nabils wrote:
Cool. I hope their is a fix for it
. It is quite a common scenario in my current project. I also tried a number of variations to try to get it working with no luck.
I think this is a bridge too far at the moment. It's not the custom types, but the way things are related to eachother. You have two queries:
1) OwnerAssistant.Where(p => p.OwnerPersonId == personId).Select(a =>new Person
{ FullName = a.AssistantPerson.FullName, List });
and
2) a.AssistantPerson.Addresses.Select(b => new Address { AddressTypeCode = b.Address.AddressType.AddressTypeCode, PrimaryPhone = b.Address.PrimaryPhone, PrimaryFax =b.Address.PrimaryFax });
The provider first executes the first query, having a dummy value at the 'list' spot (will be replaced by the results of query 2 after the merge). It then tries to construct the second one, however as the two sets have to be merged into eachother, it tries to construct a correlation filter. This filter has to tie a row or rows in query 2 with a row in query 1.
The elements returned from query 2 are not related to the elements in query 1, only indirectly via other elements. So if I have an OwnerPerson instance and a Address instance, I can't tie them together directly, there's no direct relationship. So I can't connect a row in the set of query 2 to an element returned by query 1. The query produced by query 2 therefore is incorrect, it misses information: the filter isn't applied to the right element, however as other situations aren't supported/possible, it tries to do the best it can, but of course in a query like you specified, it's not possible to do so.
This happens in our provider and not in linq to sql for example because we execute nested queries as separate sets and try to merge them together efficiently. Linq to sql for example executes a nested query per hosting element, causing many many queries to be executed, which is very slow, however they always work.
As the situation which your query describes isn't very common (as it nests indirectly related information into eachother as if it's directly related) we opted for the huge performance benefit, of course this trade off isn't beneficial for everybody, like your situation is hurt by this decision.
It is possible to solve this in some cases, as query 2 should return the field to compare with in the set of query 1 which would automatically tie rows from query 2 to the rows in query 1. However to accomplish this, a lot of code has to be added, and we cut this from v2.6 to get the provider done in time. The reason for the huge pile of code is that the query has to be analyzed to see if the field(s) to compare with are obtainable from query 2. If it was simple I'd have added it for you today, however it will take days if not weeks to add this, so we postponed this for v3 (which isn't released very soon so I have no good news for you, I'm afraid).
Sorry to have this news for you. it's the second time I have to disappoint you in this. There are workarounds like executing the queries separately, but these are obviously not optimal.
About it being quite common: the scenario of your query relates indirect related info directly to eachother. Is this due to over normalization or other situations? I also see you have a cycle in your entities (Person - PersonAddress, they point to eachother).
What I wonder is if the m:1 relationships aren't really 1:1 relationships so you could use inheritance perhaps (OwnerAssistant - Person, as OwnerAssistant is-a Person, it seems a bit odd 1 Person entity instance is related to more than 1 OwnerAssistant entity )