Here is a query I’m working on in Entity Framework 5.0.0 RC (code first) with .NET 4.0
I’m new to Entity Framework, so I’m still getting my head around how to structure the queries, particularly around selecting “child” related data.
I’m using “eager loading” so I get all of the related data at once. But I’m having a problem in that not all of the Drops are being retrieved.
var loads = context.Loads
.Include(
p => p.Device
)
.Include(
p => p.Drops.Select(
a => a.Customer
)
).Include(
q => q.Drops.Select(
b => b.Items.Select(
c => c.Product
)
)
).Where(
u => u.Id.Equals(id)
);
The problem is that in the generated SQL query, the Customers are being INNER JOINED to the Drops, thus excluding Drops which don’t have a Customer.
So how do I make it do a LEFT JOIN between those two entities?
.Include appears to do left joins – so why not .Select ?
Is there a method other than .Select that I can use which will do a LEFT JOIN ?
UPDATE
After chatting with Amiram I realised that I had set my Drop model up incorrectly. I needed to set the CustomerID column to be optional:
public class Drop
{
public int Id { get; set; }
public int? CustomerId { get; set; }
public int LoadId { get; set; }
public DateTime Date { get; set; }
public virtual Customer Customer { get; set; }
public virtual ICollection<DropItem> Items { get; set; }
}
I should have immediately thought of this, but to be honest I was put off by the fact that .Include() always does a LEFT JOIN, regardless of the cardinality in the relationship of the models. I was thinking .Select() must have some similar behaviour, but no it was just obeying how the model was configured 🙂
The drops are inner joined with customers since Drop.CustomerID is of type int and not nullable int (Look in the chat).