【问题标题】:Is accessing rows with varbinary data via LINQ causing a timeout? How to fix?通过 LINQ 访问带有 varbinary 数据的行是否会导致超时?怎么修?
【发布时间】:2009-07-23 11:19:45
【问题描述】:

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

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

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

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

这个函数循环遍历附件并用附件名称写出一个无序列表。

我偶尔会收到超时错误,这里是该错误的 sn-p:

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. 我是否正确假设这些超时是由于这样一个事实,虽然控件已经加载,但 Attachments 行是延迟加载的,并且仅从帮手?这主要是因为我抓取了大约 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 文件时不会忘记再次设置该选项。

谢谢, 詹姆斯

【问题讨论】:

    标签: sql-server asp.net-mvc linq varbinary


    【解决方案1】:
    1. Linq 延迟加载附件是对的。是否将 varbinary 数据从数据库中拖下来取决于查询。可以发一下吗?

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

    LoadWith info on MSDN

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

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

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-22
      • 1970-01-01
      相关资源
      最近更新 更多