【问题标题】:LinqToSql Producing Different Sql Queries on Different Machines for Identical CodeLinq To Sql 在不同机器上为相同代码生成不同的 Sql 查询
【发布时间】:2010-09-21 03:22:17
【问题描述】:

我有一个使用 Asp.net 和 LinqToSql 构建的用于数据访问的网站。在网站的某个部分,LinqToSql 生成一个如下所示的查询(来自我的开发机器):

select ...
from table1
left outer join table2 on table1 where ...
left outer join table3 on table2 where ...

由于 table2 和 table1 之间的连接并不总是存在,因此左外连接在这种情况下是合适的。而且由于table3和table1之间的链接是经过table2的,所以还需要一个左外连接。此 sql 返回正确的记录集。

我只是将代码放到服务器上。在相同的场景中运行相同的代码,LinqToSql 会生成以下查询:

select ...
from table1
left outer join table2 on table1 where ...
join table3 on table2 where ...

由于某种原因,它将 table2 和 table3 之间的连接呈现为内连接,而不是外连接。这会导致查询返回零记录。

开发机器和服务器都使用 .Net 3.5 SP1。开发机器是 Vista64,服务器是 Windows Server 2003 SP2。我的一位使用 Windows XP PRO 的同事也在他们的开发机器上确认了相同的正确行为。

谁能想到为什么服务器会创建不同的 sql 的原因?我怎样才能解决这个问题?这似乎与 Linq 和 .Net 在服务器上运行的方式有关。但是,我想不出任何方法来确认和解决这个问题。


Linq 代码(我只包括与 sql 更改部分相关的部分):

from Import_Table t in db.Import_Tables
select new {
   CheckedOutUser = (!t.IsCheckedOut) ? "--" : t.Import_CheckoutHistory.System_User.FirstName + " " + t.Import_CheckoutHistory.System_User.LastName,
   CheckedOutUserID = (!t.IsCheckedOut) ? 0 : t.Import_CheckoutHistory.System_UserID};

在上述描述的上下文中,table1 = Import_Table,table2 = Import_CheckoutHistory,table3 = System_User。如果我在这里注释掉以“CheckedOutUser = ...”开头的行,那么它可以在服务器上运行 - 所以这绝对是罪魁祸首。

实际返回的sql:

SELECT 
  (CASE WHEN NOT ([t0].[IsCheckedOut] = 1) THEN CONVERT(NVarChar(401),'--') ELSE ([t2].[FirstName] + ' ') + [t2].[LastName] END) AS [CheckedOutUser], 
  (CASE WHEN NOT ([t0].[IsCheckedOut] = 1) THEN 0 ELSE [t1].[system_UserID] END) AS [CheckedOutUserID]
FROM [dbo].[import_Table] AS [t0] 
LEFT OUTER JOIN [dbo].[import_CheckoutHistory] AS [t1] ON [t1].[import_CheckoutHistoryID] = [t0].[import_CheckoutHistoryID] 
LEFT OUTER/INNER JOIN [dbo].[system_User] AS [t2] ON [t2].[system_UserID] = [t1].[system_UserID] 

在开发机器上,最后一行以“Left outer”开头。在服务器上,最后一行以“Inner”开头

更新:我的解决方案是below

【问题讨论】:

  • 能否包含您的 Linq 代码?

标签: .net asp.net sql linq-to-sql


【解决方案1】:

您的生产数据库是否与您的开发数据库不同,例如SQL Server 2008 而不是 2005?我相信 LINQ to SQL 会根据它正在与之交谈的实际执行时数据库来改变它生成的 SQL。

另外,两个数据库上的架构是否完全相同?

【讨论】:

  • 他们都使用同一个数据库。
  • 因此,除非我可以使用两个版本的 .Net 3.5 SP1,否则我可以看出两者之间的唯一区别是主机环境:在 Vita 或 XP 上使用 VS 2008 + 3.5 SP1安装它工作,在安装了 .Net 3.5 SP1 的 Windows Server 2003 上它没有。
  • 你能试试另一个WS2K3盒子看看是不是真的吗?
  • 老实说,我希望内部/外部连接差异基于 LINQ 的约束理念......
  • LINQ to SQL 中没有特定于操作系统的代码。唯一影响查询的是 1. 查询,2. 数据库版本和 3. 架构。
【解决方案2】:

听起来两者之间的 LINQ to SQL 类(DBML 和/或相关代码生成)并不相同 - 具体而言,这两个表之间的关联是如何定义的。

【讨论】:

  • 我想到了这一点,并确保再次复制 dbml 文件,以防万一它们不同步。没有帮助。相同的 dbml 文件在同一个数据库中工作。
【解决方案3】:

我已经检查了以下内容:

  1. 两者使用相同的数据库
  2. 两者的代码相同
  3. 两者都有相同的 dbml 文件

我知道某些地方一定是不同步的,但我找不到。

所以我实施了以下解决方法:我向我的数据库添加了一个视图,其中包括两个左外连接。这个视图现在在我的 dbml 文件中,在上面的查询中,我引用了视图而不是表。这工作正常。

【讨论】:

  • 您有更好的建议吗?这是解决问题的唯一尝试。
猜你喜欢
  • 2016-08-28
  • 1970-01-01
  • 2018-01-11
  • 1970-01-01
  • 1970-01-01
  • 2020-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多