LINQ to Entities with EDM Inheritance
Here is model fragment:
// This class is root-EntitySet
public class InvolvedParty
{
public sting ObjectId;
}public class Organization : InvolvedParty;
public class OrganizationUnit : InvolvedParty
{
public Organization Parent;
}I want to retrieve all OrganizationUnits for given Organization (defined by its ObjectId - organizationId). I've made query:
var query = from ip in context.InvolvedParty
where ip is OrganizationUnit
//&& ((OrganizationUnit)ip).Parent.ObjectId == organizationId
select ip;I've included commented line to narrow search, but that line throws exception when query is loaded:
System.NotSupportedException: Unable to cast type 'InvolvedParty' to 'OrganizationUnit'. LINQ to Entities supports only casts of entity data model primitive types.
I could do additional filtering in two foreach loops, but it is done on client:
// 1st loop to load entities
List<OrganizationUnit> tempList = new List<OrganizationUnit>();
foreach (InvolvedPartyRepositoryIDModel.InvolvedParty item in query)
{
tempList.Add((OrganizationUnit)item);
}// 2nd loop to load navigation property
foreach (InvolvedPartyRepositoryIDModel.OrganizationUnit item in tempList)
{
item.ParentReference.Load();
if (item.Parent != null &&
item.Parent.ObjectId == organizationId)
{
// ...
}
}
Is there any way to make optimized LINQ query that will do filtering on database server?
Answers
There's probably a more linq-centric way to do this (honestly I tend to use eSQL and the ObjectQuery<T> builder methods rather than LINQ), but the way I would do it is using a builder method on the initial source of your query to apply your initial filter. That way you don't have to cast in the where clause because the only things returned are already guaranteed to be of the correct type. So your query would look like this:
var query = from ou in context.InvolvedParty.OfType<OrganizationUnit>
where ou.Parent.ObjectId == organizationId
select ou;
- DannyTo add to Danny's answer, here is something one of our developers pointed out (thanks Colin):
Cast operations are reserved for database ‘convert’ operations. ‘Is’, ‘As’ and ‘OfType<T>’ on the other hand are available for nominal type operations.
Then, a more "linquesque" way to do this would be:
var query = from ip in context.InvolvedParty
where ip is OrganizationUnit
&& (ip as OrganizationUnit).Parent.ObjectId == organizationId
select ip;Please, tell me if it works for you.
Regarding your other question, I think the more general answer is (as Danny shows) that it is a matter of taste. A more technical criteria would be: If don't know beforehand what IQueryable implementation your queries will be targeting, you will probably want to stick to LINQ. Otherwise you can freely mix and match.
- Diego
Note: OfType<T> should actually work with any IQueryable implementation. It only makes your query look a little more bumpy

All Replies
There's probably a more linq-centric way to do this (honestly I tend to use eSQL and the ObjectQuery<T> builder methods rather than LINQ), but the way I would do it is using a builder method on the initial source of your query to apply your initial filter. That way you don't have to cast in the where clause because the only things returned are already guaranteed to be of the correct type. So your query would look like this:
var query = from ou in context.InvolvedParty.OfType<OrganizationUnit>
where ou.Parent.ObjectId == organizationId
select ou;
- DannyThat works fine, thanks.
Considering that there are multiple EDM query techniques (LINQ to Entities, Entity SQL, ObjectQuery, ...), is there any gudiance (article) which one to choose and when?
To add to Danny's answer, here is something one of our developers pointed out (thanks Colin):
Cast operations are reserved for database ‘convert’ operations. ‘Is’, ‘As’ and ‘OfType<T>’ on the other hand are available for nominal type operations.
Then, a more "linquesque" way to do this would be:
var query = from ip in context.InvolvedParty
where ip is OrganizationUnit
&& (ip as OrganizationUnit).Parent.ObjectId == organizationId
select ip;Please, tell me if it works for you.
Regarding your other question, I think the more general answer is (as Danny shows) that it is a matter of taste. A more technical criteria would be: If don't know beforehand what IQueryable implementation your queries will be targeting, you will probably want to stick to LINQ. Otherwise you can freely mix and match.
- Diego
Note: OfType<T> should actually work with any IQueryable implementation. It only makes your query look a little more bumpy

Yes, that query works, thank you all.
var query = from ip in context.InvolvedParty
where ip is OrganizationUnit
&& (ip as OrganizationUnit).Parent.ObjectId == organizationId
select ip;


