实体框架 - 使用.Include()和.Select()进行“预先加载” - 如何使用LEFT JOIN而不是INNER JOIN?

时间:2012-07-26 07:36:52

标签: asp.net sql entity-framework ef-code-first eager-loading

这是我正在使用.NET 4.0在Entity Framework 5.0.0 RC(代码优先)中进行的查询

我是Entity Framework的新手,所以我仍然会考虑如何构建查询,特别是在选择“子”相关数据时。

我正在使用“急切加载”,因此我立即获得了所有相关数据。但我遇到的问题是并非所有的Drop都被检索到了。

var loads = context.Loads
            .Include(
                p => p.Device
            )
            .Include(
                p => p.Drops.Select(
                    a => a.Customer
                )
            ).Include(
                q => q.Drops.Select(
                   b => b.Items.Select(
                       c => c.Product
                   )
                )
            ).Where(
                u => u.Id.Equals(id)
            );

问题在于,在生成的SQL查询中,客户正在内联到Drops,因此排除了没有客户的Drop。

那么如何让它在这两个实体之间进行LEFT JOIN?

.Include似乎做了左连接 - 所以为什么不呢。选择?

是否有一种方法而不是。选择我可以使用哪种方法进行LEFT JOIN?


更新

与Amiram聊天后,我意识到我的Drop模型设置不正确。我需要将CustomerID列设置为可选:

public class Drop
{
    public int Id { get; set; }
    public int? CustomerId { get; set; }
    public int LoadId { get; set; }
    public DateTime Date { get; set; }

    public virtual Customer Customer { get; set; }
    public virtual ICollection<DropItem> Items { get; set; }
}

我应该立即想到这一点,但说实话,我被推迟了.Include()始终执行LEFT JOIN这一事实,无论模型关系中的基数如何。我在想.Select()必须有一些类似的行为,但不是只是遵守模型的配置方式:)

1 个答案:

答案 0 :(得分:2)

由于Drop.CustomerID的类型为int而不是nullable int(在聊天中查找),因此drop与客户内部联系在一起。