My query with Include
generates sql with Inner
join instead Left
. My FK is nullable, so I can't explain such behavior. With nullable FK I am expect normal Left
join.
Have I missed something?
Linq query:
var projectEntity = await _context.Projects
// few more includes were omitted
.Include(p => p.Invoice)
.FirstOrDefaultAsync(c => c.ProjectId == id);
Classes:
[Table("InvoicedHistory")]
public class InvoiceHistory
{
[Key]
[Column("InvoicedHistory_ID")]
public int InvoicedHistoryId { get; set; }
// few properties omitted
[Column("Project_ID")]
public int? ProjectId { get; set; }
}
public class Project
{
public int ProjectId { get; set; }
// few properties were omitted
[ForeignKey(nameof(InvoiceHistory.ProjectId))]
public virtual InvoiceHistory Invoice { get; set; }
}
Project class also use fluent api:
modelBuilder.Entity<Project>(entity =>
{
entity.ToTable("Projects");
entity.HasKey(e => e.ProjectId)
.HasName("PK_Project_Project_ID_Project");
// few statements were omitted
});
Sql which was generated: (Was hard to clean up this query. It contains several joins to include data for properties I have omitted)
SELECT [t].[Project_ID], [t].[Project_Client], [t].[Project_IrsDate], [t].[Project_Name], [t].[Client_ID], [t].[Client_Name], [t].[InvoicedHistory_ID], [t].[DateSubmitted], [t].[Project_ID0], [t0].[Debitor_ID], [t0].[Project_ID], [t0].[Debitor_ID0], [t0].[Address_Number], [t0].[Alias], [t0].[Alpha_Name], [t0].[Co], [t0].[Country_ID], [t0].[Currency_ID], [t0].[Havi_YesOrNo]
FROM (
SELECT TOP(1) [p].[Project_ID], [p].[Project_Client], [p].[Project_IrsDate], [p].[Project_Name], [c].[Client_ID], [c].[Client_Name], [i].[InvoicedHistory_ID], [i].[DateSubmitted], [i].[Project_ID] AS [Project_ID0]
FROM [Projects] AS [p]
INNER JOIN [Clients] AS [c] ON [p].[Project_Client] = [c].[Client_ID]
INNER **<<<<<<<<(expect LEFT)** JOIN [InvoicedHistory] AS [i] ON [p].[Project_ID] = [i].[InvoicedHistory_ID]
WHERE [p].[Project_ID] = 19922
) AS [t]
LEFT JOIN (
SELECT [p0].[Debitor_ID], [p0].[Project_ID], [d].[Debitor_ID] AS [Debitor_ID0], [d].[Address_Number], [d].[Alias], [d].[Alpha_Name], [d].[Co], [d].[Country_ID], [d].[Currency_ID], [d].[Havi_YesOrNo]
FROM [ProjectDebitors] AS [p0]
INNER JOIN [Debitors] AS [d] ON [p0].[Debitor_ID] = [d].[Debitor_ID]
) AS [t0] ON [t].[Project_ID] = [t0].[Project_ID]
ORDER BY [t].[Project_ID], [t].[Client_ID], [t].[InvoicedHistory_ID], [t0].[Debitor_ID], [t0].[Project_ID], [t0].[Debitor_ID0]
Look at this line -
INNER <<<<<<<<(expect LEFT)<<<<<< JOIN [InvoicedHistory] AS [i] ON [p].[Project_ID] = [i].[InvoicedHistory_ID]
Inner join makes my query return nothing, because I have no invoice info. If I manually replace it with Left
join, sql query will return me all necessary data.