实体框架6.1.0代码中的连接约定

时间:2014-04-25 04:54:18

标签: entity-framework entity-framework-6

我相信我的问题很简单(不确定答案是否也是这样):

有人知道如何强制Entity Framework使用“INNER JOIN”作为默认约定,而不是“LEFT OUTER JOIN”?

2 个答案:

答案 0 :(得分:3)

如果要明确强制执行内部或外部联接,则可以始终分别使用JoinGroupJoin方法。 (或综合等效项joinjoin ... 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)

实体框架查看关联的基数,以确定它是否可以生成首选的内部联接,或者是外部联接:

  • 必需的关联会生成内部联接。
  • 可选关联会生成外部联接。

因此,在这种情况下,它会生成ProductCategory之间的内部联接以及ProductPhoto之间的外部联接。

我认为这是一个明智的选择。如果在结果集中包含照片会突然减少获取项目的数量,那将是意外的行为。

这同样适用于其他查询形状,例如

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