EF seems to use INNER JOIN
for including a required and LEFT OUTER JOIN
for including an optional navigation property. Example:
public class Order
{
public int Id { get; set; }
public string Details { get; set; }
public Customer Customer { get; set; }
}
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
}
If I define Customer
as a required property on Order
...
public class MyContext : DbContext
{
public DbSet<Order> Orders { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Order>()
.HasRequired(o => o.Customer)
.WithMany();
}
}
...and issue this query...
using (var ctx = new MyContext())
{
var result = ctx.Orders
.Include(o => o.Customer)
.Where(o => o.Details == "Peanuts")
.FirstOrDefault();
}
...I get this SQL:
SELECT TOP (1)
[Extent1].[Id] AS [Id],
[Extent1].[Details] AS [Details],
[Extent2].[Id] AS [Id1],
[Extent2].[Name] AS [Name]
FROM [dbo].[Orders] AS [Extent1]
INNER JOIN [dbo].[Customers] AS [Extent2]
ON [Extent1].[Customer_Id] = [Extent2].[Id]
WHERE N'Peanuts' = [Extent1].[Details]
If I change in the model configuration .HasRequired(o => o.Customer)
to...
.HasOptional(o => o.Customer)
... I get exactly the same query except that INNER JOIN [dbo].[Customers] AS [Extent2]
is replaced by:
LEFT OUTER JOIN [dbo].[Customers] AS [Extent2]
From model viewpoint it makes sense because you are saying that there can never be an Order
without a Customer
if you define the relationship as required. If you circumvent this requirement by removing the enforcement in the database and if you actually have then orders without a customer you violate your own model definition.
Only solution is likely to make the relationship optional if you have that situation. I don't think it is possible to control the SQL that is created when you use Include
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…