Estou fazendo o tutorial de prática do mvcmusicstore. Notei algo ao criar o andaime para o gerenciador de álbuns (adicionar excluir editar).
Eu quero escrever código de forma elegante, então estou procurando a maneira limpa de escrever isso.
Para sua informação, estou tornando a loja mais genérica:
Álbuns = Itens
Gêneros = Categorias
Artista = Marca
Aqui está como o índice é recuperado (gerado pelo MVC):
var items = db.Items.Include(i => i.Category).Include(i => i.Brand);
Aqui está como o item para exclusão é recuperado:
Item item = db.Items.Find(id);
O primeiro traz de volta todos os itens e preenche os modelos de categoria e marca dentro do modelo de item. O segundo, não preenche a categoria e a marca.
Como posso escrever o segundo para encontrar e preencher o que está dentro (de preferência em 1 linha) ... teoricamente - algo como:
Item item = db.Items.Find(id).Include(i => i.Category).Include(i => i.Brand);
c#
asp.net-mvc
entity-framework
Ralph N
fonte
fonte
Respostas:
Você precisa usar
Include()
primeiro e recuperar um único objeto da consulta resultante:fonte
A resposta de Dennis está usando
Include
eSingleOrDefault
. O último vai de volta ao banco de dados.Uma alternativa é usar
Find
, em combinação comLoad
, para carregamento explícito de entidades relacionadas ...Abaixo um exemplo do MSDN :
Obviamente,
Find
retorna imediatamente sem fazer uma solicitação para a loja, se essa entidade já estiver carregada pelo contexto.fonte
Find
portanto, se a entidade estiver presente, não haverá viagem de ida e volta ao DB para a própria entidade. MAS, você terá uma viagem de ida e volta para cada relacionamento que estiver estabelecendoLoad
, enquanto aSingleOrDefault
combinaçãoInclude
carrega tudo de uma só vez.Load
função, a relação deve ser preenchida quando a chamada retornar. Portanto, se você ligarLoad
várias vezes para várias relações, haverá uma viagem de ida e volta a cada vez. Mesmo para uma única relação, se oFind
método não encontrar a entidade na memória, ele fará duas viagens de ida e volta: uma paraFind
e a segunda paraLoad
. Mas oInclude
.SingleOrDefault
abordagem busca a entidade e relação de uma só vez, tanto quanto eu sei (mas não tenho certeza)Você precisa converter IQueryable para DbSet
var dbSet = (DbSet<Item>) db.Set<Item>().Include("");
return dbSet.Find(id);
fonte
Não funcionou para mim. Mas eu resolvi fazendo assim.
Não sei se isso é uma solução ok. Mas o outro que Dennis me deu me deu um erro bool
.SingleOrDefault(x => x.ItemId = id);
fonte
SingleOrDefault(x => x.ItemId = id)
apenas por causa do single errado, em=
vez de duplo==
?Não existe uma maneira fácil de filtrar com uma descoberta. Mas eu vim com uma maneira próxima de replicar a funcionalidade, mas observe algumas coisas para a minha solução.
Esta solução permite que você filtre genericamente sem conhecer a chave primária no .net-core
A localização é fundamentalmente diferente porque ela obtém a entidade se ela estiver presente no rastreamento antes de consultar o banco de dados.
Além disso, ele pode filtrar por um objeto para que o usuário não precise conhecer a chave primária.
Esta solução é para o EntityFramework Core.
Aqui estão alguns métodos de extensão a serem adicionados que ajudarão você a filtrar por chave primária, para
Depois de ter esses métodos de extensão, você pode filtrar da seguinte maneira:
fonte