LinqToSql在不同的机器上为相同的代码生成不同的SQL查询

时间:2008-11-06 17:47:19

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

我有一个使用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之间的连接呈现为内连接,而不是外连接。这导致从查询返回零记录。

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

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


Linq Code(我只包括与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

3 个答案:

答案 0 :(得分:2)

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

另外,这两个数据库的模式是否完全相同?

答案 1 :(得分:0)

听起来两者之间的LINQ to SQL类(DBML和/或相关代码生成)是不一样的 - 特别是如何在这两个表之间定义关联。

答案 2 :(得分:-1)

我检查过以下内容:

  1. 两者都使用相同的数据库
  2. 两者都有相同的代码
  3. 两者都具有相同的dbml文件
  4. 我知道某些事情必须在某处不同步,但我找不到它。

    所以我实现了以下解决方法:我在数据库中添加了一个包含左外连接的视图。此视图现在位于我的dbml文件中,在上面的查询中,我引用视图而不是表。这很好。