鉴于下面的架构,我正在尝试构建一个 EF 查询,该查询返回缺少所需表单的联系人。每个联系人都有一个与 FormTypes 集合相关的 ContactType。每个联系人都需要至少有一个表单(在 ContactForm 中)与其 ContactType 相关的 FormTypes。
EF 从下面的 linq 查询生成的查询适用于 Sql Server,但不适用于 Oracle。
var query = ctx.Contacts.Where (c => c.ContactType.FormTypes.Select (ft => ft.FormTypeID)
.Except(c => c.Forms.Select(f => f.FormTypeID)).Any());
我正在重构一个数据层,以便所有适用于 Sql Server 的 EF 查询也将适用于使用 Devart 的 dotConnect 数据提供程序的 Oracle。
Oracle 抛出的错误是 ORA-00904: "Extent1"."ContactID": invalid identifier。
问题是 Oracle 显然不支持从 2 级或更深的嵌套子查询中的查询引用表列。Oracle 抛出的行是在引用“Extent1”.“ContactID”的除外(或减号)子查询中。“Extent1”是在查询顶层定义的联系人的别名。这是 Devart 对 Oracle 限制的解释。
我为许多查询解决此问题的方法是重写它们以使用 SelectMany() 和在某些情况下使用 Join() 将表之间的关系从 Where() 谓词中移到查询的主体中。这往往会使发送到数据库服务器的查询变得扁平化,并最大限度地减少或消除 EF 产生的子查询。 这是使用左外连接解决的类似问题。
"Extent1"."ContactID" 列存在,EF 和 Devart 生成的查询的命名语法不是问题。
任何关于如何重写此查询的想法将不胜感激。目标是一个查询,该查询返回联系人缺少适用于 Oracle 和 Sql Server 的联系人的 ContactType 所需的 FormType 表单。