1

在 Windows 2008 R2 Server 上部署时,我的应用程序遇到了一个非常奇怪的问题。

鉴于这个非常简单的 LINQ 片段:

return From
    invoice In Me.Invoices
Where
    loggedCustomerID.Contains(invoice.Contract.CustomerID)
Order By
    invoice.Date Descending

该应用程序可以工作,但在某些情况下(在客户服务器上),生成的 T-SQL 非常奇怪:

 SELECT 
    [Extent1].[ContractID] AS [ContractID], ...
 FROM
    [dbo].[Invoice] AS [Extent1]
    INNER JOIN [dbo].[Contract] AS [Extent2] ON 
             [Extent1].[ContractID] = [Extent2].[ContractID]
    LEFT OUTER JOIN [dbo].[Contract] AS [Extent3] ON 
             [Extent1].[ContractID] = [Extent3].[ContractID]

 WHERE 
      [Extent2].[CustomerID] = 482283 
   OR [Extent3].[CustomerID] IN (498565,482282,498564,498566)
  • 表链接多次(?)
  • IN语句被分解为多个 T-SQL 条件而不是单个IN语句

显然,相同的包在我的系统上运行良好,生成了正确的查询,而无需多次链接同一个表并且只创建一个IN语句。

我使用的是 EF 5.0,但与 Framework 4.0 兼容(因此程序集显示版本 4.4)。这是这个问题的根本原因吗?

这里有什么问题?

看起来行为与此有关? Entity Framework 4 中的左外连接太多?

4

2 回答 2

1

我在 NHibernate 中遇到过类似的行为,也许你会发现任何相似之处。

我们得到了简单的parent->children关系。关键是关系是双向的,因此父级引用了所有子级,并且每个子级都引用回父级。

NHibernate 支持我关闭的延迟获取。因此,一旦我决定获取整个聚合,它就会产生有趣的查询,我的意思是父母和所有孩子。

就像是:

select ... from parent ... left join ... children ... left join parent

由于 Nhibernate 在底层使用一级缓存,它无法自动发现这些父实例是相等的,因为在查询执行时父缓存是空的。

后来在解析生成的数据库数据集期间,NHibernate 发现父实体具有相同的主标识符并仅返回一个真实实例。

于 2013-08-14T16:28:30.657 回答
0

最后我能够进行一些测试。似乎 EF T-SQL 生成很大程度上取决于底层框架。事实上,只要将框架升级到 4.5 就可以解决上述问题。

于 2013-08-23T18:58:01.450 回答