我相信我的问题很简单(不确定答案是否也是这样):
有人知道如何强制Entity Framework使用“INNER JOIN”作为默认约定,而不是“LEFT OUTER JOIN”?
答案 0 :(得分:3)
如果要明确强制执行内部或外部联接,则可以始终分别使用Join
或GroupJoin
方法。 (或综合等效项join
和join ... into
)。
但是,一般来说,在LINQ语句中,您应该避免使用显式连接语句。请改用导航属性。导航属性是已在实体之间定义的关联。通过导航属性查询是通过连接查询而无需手动编码。但这些联合何时会成为内在或外在的?
采取以下三个简单的课程:
class Product
{
public int Id { get; set; }
public string Name { get; set; }
public int CategoryId { get; set; }
public Category Category { get; set; }
public int? PhotoId { get; set; }
public Photo Photo { get; set; }
}
class Category
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Product> Products { get; set; }
}
class Photo
{
public int Id { get; set; }
public byte[] Image { get; set; }
}
如果我们查询包含其类别和照片的产品会怎样?
context.Products.Include(p => p.Category).Include(p => p.Photo)
实体框架查看关联的基数,以确定它是否可以生成首选的内部联接,或者是外部联接:
因此,在这种情况下,它会生成Product
和Category
之间的内部联接以及Product
和Photo
之间的外部联接。
我认为这是一个明智的选择。如果在结果集中包含照片会突然减少获取项目的数量,那将是意外的行为。
这同样适用于其他查询形状,例如
context.Products.Select(p => new { p.Name, Cat = p.Category.Name })
这会生成内部联接。
context.Products.Select(p => new { p.Name, Cat = p.Photo.Image })
这会生成外部联接。
如果在后一个例子中你只查询Photo != null
的产品,那么EF还不够智能(但是?)才能看到它可以生成内连接。这可能是您想要编写显式LINQ连接的情况。
因此,这种对导航属性的关注将您的注意力从......转移到了
如何强制Entity Framework使用“INNER JOIN”
...更多与业务逻辑相关的决策是否应该是必需的协会。
答案 1 :(得分:1)
join
子句默认生成Inner join
。
from x in table1
join y in table2 on x.id equals y.id
要使其充当外部联接,您可以使用DefaultIfEmpty
方法,如下所示:
from x in table1
join y in table2 on x.id equals y.id into jointable
from z in jointable.DefaultIfEmpty()
如果您将正在执行的查询添加到您的问题中,我们可以找出为什么生成Left Outer Join
。
这是解释事物的好资源:http://msdn.microsoft.com/en-us/library/bb311040.aspx