EF, кажется, использует INNER JOIN
для включения обязательных и LEFT OUTER JOIN
для включения необязательного навигационного свойства.Пример:
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; }
}
Если я определю Customer
как обязательное свойство для 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();
}
}
... и выдам этот запрос...
using (var ctx = new MyContext())
{
var result = ctx.Orders
.Include(o => o.Customer)
.Where(o => o.Details == "Peanuts")
.FirstOrDefault();
}
... Я получаю этот 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]
Если я изменю в конфигурации модели .HasRequired(o => o.Customer)
на ...
.HasOptional(o => o.Customer)
... Я получаю точно такой же запрос за исключением того, что INNER JOIN [dbo].[Customers] AS [Extent2]
заменяется на:
LEFT OUTER JOIN [dbo].[Customers] AS [Extent2]
С точки зрения модели это имеет смысл, потому что вы говорите, что никогда не может быть Order
безCustomer
, если вы определяете отношение как обязательно .Если вы обойдете это требование, удалив принудительное применение в базе данных, и если у вас действительно есть заказы без клиента, вы нарушите собственное определение модели.
Только решение может сделать отношение необязательным если у вас есть такая ситуация.Я не думаю, что можно контролировать SQL, который создается при использовании Include
.