我有一个使用 SubSonic 2.1.0 版本的 Web 应用程序。在添加一些新功能时,我发现了该版本中的一个错误,该错误已在 2.2.0 中修复。
在我的开发箱上,我切换了引用的 DLL 的版本,一切正常。
更新运行 IIS 7.5 的 Windows 2008 R2 服务器后,该错误仍然存在。
我搜索了服务器并用最新版本替换了 SubSonic.dll 的每个实例。
重新启动网站、应用程序池,然后重新启动整个服务器。
我运行了 SysInternal 的进程资源管理器并检查了该站点的 w3wp.exe 进程,根据它,w3wp.exe 引用了 SubSonic.dll 的 2.2.0 版本。
我已将数据库和站点文件从该 Windows 2008 服务器复制到另一个 2008 服务器(从未加载过 v2.1.0 的服务器),并确认那里没有出现该错误。
根据症状,似乎服务器正在保留 2.1.0 版本的 DLL,但我不知道它在哪里以及如何摆脱它。
附加信息:
我检查了 GAC,没有 SubSonic dll。
使用 Windows SDK 6.1 中的 gacutil 将 2.2.0 安装到 GAC 中
在服务器上设置一个新的站点和应用程序池,并从我的开发箱中上传站点文件的最新副本。
站点是 C# .Net 2.0,使用 MVC 1 和 nHaml 2.0 作为视图引擎。
使用 cygwin find 在文件系统中搜索与 2.1 DLL 大小相同的文件。
发现了 Windows 搜索框中没有的几个副本,它们只是在备份文件夹中,不应该被使用,以防万一被删除了。
与 2.1.0 版本大小相同的仅剩文件是:
./Windows /System32/DriverStore/FileRepository/prnca00z.inf_amd64_neutral_27f402ce616c3ebc/Amd64/CNBDR4_5.DLL
./Windows/winsxs/amd64_microsoft-windows-getuname.resources_31bf3856ad364e35_6.1.7600.16385_en-us_eca42f29f7e4d0ea/getuname.dll.mui
./Windows/winsxs/amd64_prnca00z.inf_31bf3856ad364e35_6.1.7600.16385_none_ea189c313845a10e/Amd64/CNBDR4_5.DLL
./Windows/winsxs/x86_microsoft-windows-getuname.resources_31bf3856ad364e35_6.1.7600.16385_en-us_908593a63f875fb4/getuname.dll.mui
这似乎与 SubSonic DLL 无关。
2010 年 8 月 30 日更新
怀疑所使用的 DLL 版本存在错误,原因如下:
发生的错误相当具体,并且在我的开发环境中,当我在 DLL 的 2.1.0 和 2.2.0 之间进行更改时,该错误可预测地发生在 2.1.0 下,而不是 2.2.0 下。
我还将该网站放到了不同的服务器上,并且它在 2.2.0 上运行良好,因此它的运行并不是我的开发箱所独有的。
基本上,在 2.1.0 版本中,执行分页结果查询时,WHERE 子句元素会加倍,因此生成的查询最终会以“WHERE CreatedOn > '8-1-2010' AND CreatedOn > '8-1-2010'”结束。
尽管是多余的,但从语法上来说,这是可以执行的。
当您添加 SubQuery 时会出现错误,因为 SubQuery 对象的 SQL 生成了两次,第二次不是以 WHERE 开头,而是以 AND 开头,因为从第一次生成 SQL 开始,对象上的布尔标志就会跟踪 WHERE 是否已启动,此时为真。
因此在 2.1.0 下你将得到“WHERE id IN (SELECT id FROM table WHERE CreatedOn > '8-1-2010') AND id IN (SELECT id FROM table AND CreatedOn > '8-1-2010')”
在 2.2.0 中,分页查询的 WHERE 子句不会重复其条件,因此 SubQuery 不会生成不正确的 SQL 语法。
SQL 生成发生在 DLL 中,我可以通过 SQL Profiler 观察发现 2.1.0 生成了错误的语法,但是当我使用 2.2.0 在本地运行时,语法是正确的。
因为这个错误是一种非常特殊的情况,所以网站通常运行良好,只有在特定的搜索查询中才会发生这种情况,并且很容易重复发生这种情况,没有代码、数据或数据结构或其他环境变化,它在 2.1.0 下出错,但在 2.2.0 下不会出错。
我之前没有给出关于这个错误的具体信息,因为它似乎与解决问题无关,解决方案应该是关于从 asp.net 站点的 bin 目录加载的任何第三方 dll 被缓存,并且在应用程序池、服务和机器重新启动、新站点容器创建、删除和重新上传所有站点文件等之后不会更新版本。
答案1
更新:尝试删除以下内容:
%SystemRoot%\Microsoft.NET\Framework<64>\<versionNumber>\Temporary ASP.NET Files
对相关路径执行此操作(取决于您的.net 版本和 32/64 位)。
更新前:我不熟悉 subsonic。但也许它会生成程序集或存储过程。不知何故,即使在 dll 升级后,这个东西的旧版本仍被保留。使用进程监视器检查应用程序正在从磁盘加载什么。如果相关,还请检查存储过程。
答案2
几个问题:
- 在将网站部署到 IIS7/Win2k8 服务器之前,您是否重建了网站?即,部署的网站是否引用 2.1.0 或 2.2.0 版本?
- 有问题的程序集是强名称的还是弱名称的?如果是强名称的,它会被安装到 GAC 吗?
- 这个错误的存在是否就是您认为问题出在 DLL 版本的唯一依据?
答案3
虽然我必须承认我没有完整地阅读你的问题,但我想猜测一下问题可能是什么。我试图将此作为评论发布,但出于某种原因,该网站不允许我这样做。
问题可能不在于 Subsonic DLL 本身,而在于它引用的另一个 DLL。Subsonic.dll 的 A 版本可能根本不引用这个其他 DLL,但 B 版本可能引用它,因此这就是您得到不同行为并且无法找到问题的原因。
您需要使用一些好的调试工具,一步一步地检查事件流,直到发现不正确的事情。
我也认为这个问题更适合 StackOverflow。我相信这是一个与编程相关的问题,尤其是与程序集引用有关的问题。
尝试在 StackOverflow 上发帖,你会发现人们从与通常的服务器管理员不同的角度看待这个问题。
答案4
我发现了这个问题。
当我在各种机器上进行更多测试时,我最终能够重现该错误。
站点代码 + SubSonic 2.1.0 = 错误
站点代码 + SubSonic 2.2.0 + SQL Server 2008 = 有效
站点代码 + SubSonic 2.2.0 + SQL Server 2008 SP1 = 错误
2.1.0 中无论发生什么都会发生错误,2.2.0 中修复了这个问题。还有一个额外的逻辑错误,如果你使用的是 2008 SP1,就会出现新的错误,但其症状与我在 2.1.0 中遇到的原始问题相符。
在注意到 SQL 数据库版本的差异并通过升级我的开发箱进行确认然后发生错误后,我现在能够找到一些额外的信息,因为我知道我正在查看一个新问题。
http://github.com/subsonic/SubSonic-2.0/issues
具体来说是问题 7,但问题 2、8 和 9 似乎都密切相关,并且可能出现相同格式错误的 SQL 语法。