1

我在 SQL 中有许多表。一个是Controls(一种典型的 CRUD 对象),一个是Attachments附件通过 FK引用控件(可以有很多附件)。除其他外,附件还包括名称和带有文件数据的 varbinary 列。

通过 linq,Control有一个 Attachments 属性。

我有一个控件视图 (MVC),它显示了很多信息,包括现有附件的列表。该列表是通过辅助方法完成的:

public static string FileBox(this HtmlHelper helper, string name, IEnumerable<Models.Attachment> files, bool writable)
    { ... }

该函数遍历附件并写出带有附件名称的无序列表。

我偶尔会收到超时错误,这是该错误的一个片段:

System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

...

at System.Data.Linq.SqlClient.ObjectReaderCompiler.ObjectReader`2.MoveNext()
   at System.Data.Linq.EntitySet`1.Load()
   at System.Data.Linq.EntitySet`1.GetEnumerator()
   at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
   at IRSoxCompliance.Helpers.Html.FileBox(HtmlHelper helper, String name, IEnumerable`1 files, Boolean writable) in C:\Documents and Settings\Administrator\My Documents\Visual Studio 2008\Projects\IRSoxCompliance\IRSoxCompliance\IRSoxCompliance\Helpers\Html.cs:line 228
   at ASP.views_edit_control_edit_test_aspx.__Render__control1(HtmlTextWriter __w, Control parameterContainer) in c:\inetpub\wwwroot\Views\Edit\Control_Edit_Test.aspx:line 109

...

所以...

  1. 我是否正确地假设这些超时是由于这样一个事实,即当控件已经加载时,附件行是延迟加载的,并且只从帮助程序加载?这主要是因为我抓取了大约 50 mb 的我不需要的数据?

  2. 我该如何防止这种情况?a) 我想避免拆分桌子。b) 我可以在控件上创建一个 AttachmentsNoBinary 部分属性,该属性返回一个新类,该类除了二进制文件之外的所有内容?c)看来我可以只在二进制列上打开“延迟加载”。这行得通吗?如果是这样——我已经强调不更改 DBML 中的任何内容,因为我有清除表然后重新加载的习惯。所以我会失去这个设置。有什么办法可以确保我不会丢失它吗?我可以从我的部分设置它吗?或者也许是一个可以断言它已打开的单元测试?

解决方案:根据答案,我意识到不是:

foreach (Attachment file in controls.Attachments) {
  response.write(file.name);
}

我可以改为:

foreach (string filename in controls.Attachments.Select(a => a.name)) {
  response.write(filename);
}

虽然我最终延迟加载了 varbinary 列,但希望我在重置 dbml 文件时不要忘记再次设置该选项。

谢谢,詹姆斯

4

1 回答 1

0
  1. 你是对的,Linq 懒加载你的附件。是否将 varbinary 数据从数据库中拖下来取决于查询。你能发帖吗?

  2. 您无需更改数据库的结构即可解决问题。确保您的查询没有触及 varbinary 字段 - 您需要适当的选择/投影来确保这一点。此外,如果您知道您总是会获取与控制器相关的所有附件,您可以使用 LoadWith 来指示 Linq 一次获取所有附件,而不是按需延迟加载。这将减少完成工作所需的数据库往返次数。

LoadWith MSDN 上的信息

还值得检查您的索引在表上是否正常。

要真正了解数据库中发生的点 SQL 查询分析器,然后运行代码。您将确切地看到哪些 SQL 正在访问数据库,并且可以在 Management Studio 中抓取并运行它,以确切了解哪些数据被拖回。

希望这个对你有帮助。

于 2009-08-06T21:20:02.760 回答