Está acessando linhas com dados varbinary via LINQ causando um tempo limite? Como consertar?

StackOverflow https://stackoverflow.com/questions/1171104

Pergunta

Eu tenho um número de tabelas no SQL. Um deles é Controles (a CRUD típico tipo de objeto) e um é Anexos . Anexos referências Controles através de um FK (pode haver muitos anexos). Anexos também inclui, entre outras coisas, um nome e uma coluna varbinary com dados do arquivo.

Através linq, Controle tem uma propriedade anexos.

Eu tenho controles de exibição (MVC) que apresenta uma série de informações, incluindo uma lista dos anexos existentes. Este item é feita através de um método auxiliar:

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

Esta função percorre os anexos e escreve uma lista não ordenada com os nomes de anexos.

Raramente, eu recebo um erro de tempo limite, e aqui está um trecho desse erro:

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

...

Então ...

  1. Am I correto supor que estes tempos de espera são devido ao fato de que, enquanto o controle já foi carregado, o Anexos linhas são preguiçosos-carregado, e só sendo carregado a partir do ajudante? E que este é principalmente devido ao fato de que eu estou agarrando talvez 50 mb de dados que eu não preciso?

  2. Como posso evitar isso? a) Eu gostaria de evitar a divisão da mesa. b) Posso criar uma propriedade parcial AttachmentsNoBinary sobre o controle que retorna uma nova classe que tem tudo, mas o binário? c) Parece que eu possa ligar 'atraso carregado' apenas na coluna binária. Isso vai funcionar? Se assim for - Eu fiz-lhe um ponto de não mudar nada no DBML, porque eu tenho o hábito de limpar a mesa e, em seguida, recarregar. Então eu perderia essa configuração. Existe alguma maneira de ter certeza que eu não perdê-lo? Posso defini-lo do meu parcial? Ou talvez um teste de unidade que pode afirmar que ele é ligado?

Solução : Com base na resposta, eu percebi que em vez de:

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

I vez pode fazer:

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

Embora eu acabei defer-carregar a coluna varbinary, esperando que eu não esqueça de configurar essa opção novamente deve redefinir meu arquivo dbml.

Obrigado, James

Foi útil?

Solução

  1. Está certo que Linq é preguiçoso carregando seus anexos. Se é ou não está arrastando os dados varbinary para baixo do banco de dados depende da consulta. você pode publicá-la?

  2. Você não precisa alterar a estrutura do seu banco de dados para resolver o problema. Certifique-se de que sua consulta não está a tocar o campo varbinary - você vai precisar de um select / projeção adequada para garantir isso. Além disso, se você sabe que você está sempre indo para obter todos os anexos relacionados a um controlador você poderia usar LoadWith para instruir Linq para obtê-lo de uma só vez, em vez de carregamento lento na demanda. Isso irá reduzir o número de viagens de ida de banco de dados necessário para fazer o trabalho.

LoadWith informações sobre MSDN

Também vale a pena verificar que seus índices são ok nas mesas.

Para obter alguma visão real sobre o que está acontecendo ponto de SQL Query Analyzer em seu banco de dados e, em seguida, executar o código. Você vai ver exatamente o que SQL é bater o banco de dados e pode pegar e executá-lo no Management Studio para ver exatamente quais os dados que está sendo arrastado de volta.

Espero que isso ajude um pouco.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top