如何使用 .Include 查询实体框架 6 强制外部联接

Posted

技术标签:

【中文标题】如何使用 .Include 查询实体框架 6 强制外部联接【英文标题】:How to force outer join with .Include query Entity Framework 6 【发布时间】:2017-10-19 10:48:21 【问题描述】:

我的数据模型如下。 UserPhone 是必需的,但导航属性是可选的,只要 User 的表可以为空:

public class Request

    [Key]
    public int Id get;set;
    [Required]
    public string UserPhone get;set;
    [ForeignKey("UserPhone")]
    public virtual User User get;set;


public class User

    [Key]
    public string UserPhone get;set;

Users 表在请求输入系统后填充。在输入请求和未填充用户之间的某个位置我正在尝试获取用户的所有请求(如果存在)(外部连接)。

db.Requests.Include(r=>r.User).FirstOrDefault();

这给了我零结果,因为 EF 进行了内部连接(我的 UserPhone 字段已定义,并且是外键,它是 Requests 表所必需的)。

如何正确定义映射才能使用包含映射?我需要include,因为我的案例涉及了更多的表,我想通过手动连接来完成所有操作

【问题讨论】:

【参考方案1】:

它确实是INNER JOIN,因为您已将 FK 属性配置为 [Required]。因此,从 EF 的角度来看,相关的 User 记录应该始终存在。

如果不是这样,则意味着您的模型和数据库不同步。从Request.UserPhone 属性中删除[Required] 注释就完成了。

更新: EF 在很大程度上依赖于通过约定、数据注释和流畅配置提供的模型元数据。所有的决定都是基于这些信息做出的。例如,当您根据需要配置持久原语属性时,查询中针对该属性的所有null 检查都将被删除并在查询转换时解析为常量truefalse。这同样适用于关系。内部查询(Include 是一个特定的查询构造)它们被 EF 用来确定连接的基数和连接的 type。在查询关系的 one 一侧时,FK 的 Required / Optional 属性控制是否生成 INNERLEFT OUTER 连接。

因此,控制 EF 行为的唯一方法是为其提供来自实体模型的正确元数据。无法动态控制/更改特定操作的行为。

【讨论】:

我提到我的数据模型是根据需求定义的。我的request 表需要定义userPhone(必需)。同时用户表不需要用户存在(外部连接)。所以问题是如何告诉 EF 不要进行内部连接。 我已经告诉过你了。您的业​​务/域模型要求是什么并不重要。 EF“实体”模型代表存储模型和FK关系,因此应该反映数据库表NULL/NOT NULL和FK约束。这是 EF 要求,如果你不遵守它(谎言 EF),不要指望 EF 为你生成正确的查询。 I already told you - 不,你没有。您的回答证实,当我说这是我的要求时,我应该更新我的数据模型。当您确认这是 EF 要求时,评论中的答案更有意义。你应该把它放在答案中。 啊,抱歉(英语不是我的自然语言)- 我认为这很明显 :) 抱歉,让我想想如何更好地表述它。

以上是关于如何使用 .Include 查询实体框架 6 强制外部联接的主要内容,如果未能解决你的问题,请参考以下文章

加入前包含不起作用实体框架6

如何在从 .Include 实体框架查询返回的数据上指定 where 子句?

强制实体框架使用 datetime 而非 datetime2

实体框架在左连接时强制内连接使用 DefaultIfEmpty() 语法

如何使用 Oracle 的实体框架支持强制帕斯卡案例?

如何强制实体框架插入标识列?