Entity Framework - Selective Condition on Included Navigation Property

Assume I have these simplified EF generated entities...

public class PurchaseOrder
     public int POID {get;set;}
     public int OrderID {get;set;}
     public int VendorID {get;set;}
     public IEnumerable<Order> Orders {get;set;}

public class Order
     public int OrderID {get;set;}
     public decimal Price {get;set;}
     public IEnumerable<Item> Items {get;set;}

public class Item
     public int OrderID {get; set;}
     public string SKU {get;set;}
     public int VendorID {get;set;}
     public Order Order {get;set;}

Business Logic:

An order can have multiple POs, one for each distinct vendor on the order (vendors are determined at the Item level).

How Can I selectively Include Child Entities?

When querying for POs, I want to automatically include child entites for Order and Item.

I accomplish this, using Include()...


This does it's job and pulls back related entities, but, I only want to include Item entities whose VendorID matches the VendorID of the PurchaseOrder entity.

With traditional SQL, I'd just include that in the JOIN condition, but EF builds those internally.

What LINQ magic can I use tell EF to apply the condition, without manually creating the JOINs between the entities?


You can't selectively pull back certain child entities that match a certain condition. The best you can do is manually filter out the relevant orders yourself.

public class PurchaseOrder
     public int POID {get;set;}
     public int OrderID {get;set;}
     public int VendorID {get;set;}
     public IEnumerable<Order> Orders {get;set;}

     public IEnumerable<Order> MatchingOrders {
         get {
            return this.Orders.Where(o => o.VendorId == this.VendorId);

You can't. EF doesn't allow conditions for eager loading. You must either use multiple queries like:

var pos = from p in context.PurchaseOrders.Include("Order")
          where ...
          select p;
var items = from i in context.Items
            join o in context.Orders on new { i.OrderId, i.VendorId} 
               equals new { o.OrderId, o.PurchaseOrder.VendorId }
            where // same condition for PurchaseOrders
            select i;

Or you can use projection in single query:

var data = from o in context.Orders
           where ...
           select new
                  Order = o,
                  PurchaseOrder = o.PurchaseOrder,
                  Items = o.Items.Where(i => i.VendorId == o.PurchaseOrder.VendorId)

You could use the IQueryable-Extensions here:


The Extension builds dynamically an anonymous type. This will be used for projection as described by @Ladislav-Mrnka.

Then you can do this:

var query = query.SelectIncluding( new List<Expression<Func<T,object>>>>(){

//Example how to retrieve only the newest history entry
x => x.HistoryEntries.OrderByDescending(x => x.Timestamp).Take(1),

//Example how to order related entities
x => x.OtherEntities.OrderBy(y => y.Something).ThenBy(y => y.SomeOtherThing),

//Example how to retrieve entities one level deeper
x => x.CollectionWithRelations.Select(x => x.EntityCollectionOnSecondLevel),

//Of course you can order or subquery the deeper level
//Here you should use SelectMany, to flatten the query
x => x.CollectionWithRelations.SelectMany(x => x.EntityCollectionOnSecondLevel.OrderBy(y => y.Something).ThenBy(y => y.SomeOtherThing)),


Need Your Help

“undefined reference to pthread_atfork” while I was trying to port libpcsclite to Android

android android-ndk

Android ndk told me "undefined reference to pthread_atfork" while I was trying to cross compile libpcsclite for Android

Prevent string array from being reformatted to scientific


I am working on a macro that takes a column of cells with a list of standards delimited by a " " and adds them to an array if they are a unique value. I ask the user where they would like to put the