Pergunta

Eu tenho uma consulta LINQ mapeados com o Entity Framework que é algo como isto:

image = this.Context.ImageSet
                    .Where(n => n.ImageId == imageId)
                    .Where(n => n.Albums.IsPublic == true)
                    .Single();

Isso retorna um objeto de imagem única e funciona como pretendido.

No entanto, esta consulta retorna todas as propriedades da minha mesa de imagem no DB. Em circunstâncias normais, isso seria bom, mas essas imagens contêm uma grande quantidade de dados binários que leva muito tempo para retorno.

Basicamente, em que estado atual minha consulta linq está fazendo:

Select ImageId, Name, Data
From Images
...

Mas eu preciso de uma consulta que faz isso instread:

Select ImageId, Name
From Images
...

Observe que eu quero carregar tudo, exceto o de dados. (Eu posso obter esses dados em uma segunda passagem assíncrona)

Foi útil?

Solução

Infelizmente, se estiver usando LINQ to SQL, não há solução ótima.

Você tem 3 opções:

  1. Você voltar a Entidade, com rastreamento Contexto e tudo, neste caso, Imagem, com todos os campos
  2. Você escolhe seus campos e retornar um tipo anônimo
  3. Você escolhe seus campos e retornar uma classe personalizada fortemente tipado, mas você perde rastreamento, se é isso que você quer.

Eu amo LINQ to SQL, mas isso é a maneira que é.

Minha única solução para você seria a de reestruturar o seu banco de dados e mover toda a grande de dados em uma tabela separada, e vinculá-lo a partir da tabela de imagem.

Desta forma, quando voltar Imagem só iria retornar uma chave no novo campo dataID, e então você pode acessar os dados mais pesado quando e se você precisasse.

aplausos

Outras dicas

Isto irá criar uma nova imagem com apenas os campos definidos. Quando você voltar para obter os dados para as imagens que você selecionar, eu sugiro ir em frente e obter o conjunto completo de dados em vez de tentar mesclá-lo com os dados id / nome existentes. Os campos id / nome são presumivelmente pequeno em relação aos dados eo código será muito mais simples do que tentar fazer a mesclagem. Além disso, ele pode não ser necessário para realmente construir um objeto de imagem, usando um tipo anônimo pode atender às suas finalidades tão bem.

image = this.Context.ImageSet
                    .Where(n => n.ImageId == imageId)
                    .Where(n => n.Albums.IsPublic == true)
                    .Select( n => new Image { ImageId = n.ImageId, Name = n.Name }
                    .Single();

[Se estiver usando Linq 2 SQL] Dentro o designer DBML, há uma opção para fazer colunas da tabela individuais atrasar-carregado. Defina como true para o seu grande campo binário. Em seguida, esses dados não está carregado até que seja realmente utilizado.

[Pergunta para todos vocês: Alguém sabe se os quadros entidade de apoio atrasou carregado varbinary / de varchar em MSVS 2010? ]

Solução # 2 (para estrutura de entidade ou linq 2 sql):

Criar uma exibição da tabela que inclui apenas a chave primária eo varchar (max) / varbinary (max). Mapear isso em EF.

Dentro de seu designer Entity Framework, exclua o varbinary (max) / varchar propriedade (max) a partir da definição da tabela (deixando-a definida apenas na vista). Isso deve excluir o domínio das operações de leitura / gravação a essa tabela, mas você pode verificar que, com o logger.

Geralmente você vai acessar os dados através da tabela que exclui o blob de dados. Quando você precisar do blob, você carrega uma linha da vista. Eu não tenho certeza se você vai ser capaz de escrever para a vista, eu não sei como você faria escreve. Você pode ser capaz de escrever para a vista, ou você pode precisar de escrever um procedimento armazenado, ou você pode busto para fora um arquivo DBML para uma mesa de.

Você não pode fazê-lo com LINQ , pelo menos por agora ...

A melhor abordagem que eu sei é criar View para a tabela que você precisa sem grandes campos e uso LINQ com que View.

Como alternativa, você poderia usar o selecione Novo na expressão de consulta ...

var image =
(
    from i in db.ImageSet
    where i.ImageId == imageId && i.Albums.IsPublic
    select new
    {
        ImageId = i.ImageId,
        Name = i.Name
    }
).Single()

As expressões de consulta LINQ realmente ser convertidos para a expressão Lambda em tempo de compilação, mas eu prefair usando a expressão de consulta geral, porque acho que é mais legível e compreensível.

Graças :)

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