Com a remoção do Entity Framework Core, dbData.Database.SqlQuery<SomeModel>
não consigo encontrar uma solução para construir uma consulta SQL bruta para minha consulta de pesquisa de texto completo que retornará os dados das tabelas e também a classificação.
O único método que vi para construir uma consulta SQL bruta no Entity Framework Core é por meio do dbData.Product.FromSql("SQL SCRIPT");
qual não é útil, pois não tenho um DbSet que mapeie a classificação retornada na consulta.
Alguma ideia???
c#
entity-framework-core
David Harlow
fonte
fonte
Respostas:
Depende se você está usando EF Core 2.1 ou EF Core 3 e versões superiores .
Se você estiver usando EF Core 2.1
Se estiver usando o EF Core 2.1 Release Candidate 1 disponível desde 7 de maio de 2018, você pode aproveitar as vantagens do novo recurso proposto, que é o tipo de consulta.
Qual é o tipo de consulta ?
Quando usar o tipo de consulta?
Assim, você não precisa mais fazer todos os hacks ou soluções alternativas propostas como respostas à sua pergunta. Basta seguir estas etapas:
Primeiro você definiu uma nova propriedade de tipo
DbQuery<T>
ondeT
é o tipo da classe que carregará os valores da coluna de sua consulta SQL. Então, em seuDbContext
você terá isto:Em segundo lugar, use o
FromSql
método como você faz comDbSet<T>
:Observe também que
DdContext
s são classes parciais , portanto, você pode criar um ou mais arquivos separados para organizar suas definições 'DbQuery SQL bruto' da maneira que melhor lhe convier.Se você estiver usando EF Core 3.0 e versões superiores
O tipo de consulta agora é conhecido como tipo de entidade sem chave . Como dito acima, os tipos de consulta foram introduzidos no EF Core 2.1. Se você estiver usando EF Core 3.0 ou versão superior, você deve agora considerar o uso de tipos de tntity sem chave porque os tipos de consulta agora estão marcados como obsoletos.
Ainda temos os mesmos cenários dos tipos de consulta para quando usar o tipo de entidade sem chave.
Então, para usá-lo, você precisa primeiro marcar sua classe
SomeModel
com[Keyless]
anotação de dados ou por meio de configuração fluente com.HasNoKey()
chamada de método como abaixo:Após essa configuração, você pode usar um dos métodos explicados aqui para executar sua consulta SQL. Por exemplo, você pode usar este:
fonte
bit
)?[NotMapped]
àSomeModels
classe não funciona para mim. Eu perdi alguma coisa?DbQuery
uso apenasDbSet
com tipos de entidade sem chave .modelBuilder.Entity<MyData>().HasNoKey().ToView(null);
@ Jean-Paul, acho que isso resolve seu problemaCom base nas outras respostas, escrevi este auxiliar que realiza a tarefa, incluindo exemplo de uso:
Uso:
Eu pretendo me livrar dele assim que o suporte integrado for adicionado. De acordo com uma declaração de Arthur Vickers da equipe EF Core, é uma alta prioridade para o pós 2.0. O problema está sendo rastreado aqui .
fonte
No EF Core você não pode mais executar sql bruto "livre". Você deve definir uma classe POCO e um
DbSet
para essa classe. No seu caso, você precisará definir a Classificação :Como certamente será somente leitura, será útil incluir a
.AsNoTracking()
chamada.EDIT - Quebrando a mudança no EF Core 3.0:
DbQuery () agora está obsoleto, ao invés DbSet () deve ser usado (novamente). Se você tiver uma entidade sem chave, ou seja, não requer chave primária, você pode usar o método HasNoKey () :
Mais informações podem ser encontradas aqui
fonte
DbContext
para incluir uma nova propriedadeDbSet<Rank> Rank { get; set; }
. Que implicações isso terá agora em referência ao linq? Ou seja, não poderemos agora usar uma instrução comoDBContext.Rank.Where(i => i.key == 1)
e essa instrução não terá implementação em SQL e, portanto, falhará?Você pode executar sql bruto no EF Core - Adicione esta classe ao seu projeto. Isso permitirá que você execute o SQL bruto e obtenha os resultados básicos sem ter que definir um POCO e um DBSet. Consulte https://github.com/aspnet/EntityFramework/issues/1862#issuecomment-220787464 para obter o exemplo original.
Aqui está um exemplo de como usá-lo:
fonte
Por enquanto, até que haja algo novo da EFCore, eu usaria um comando e mapearia manualmente
Tente SqlParameter para evitar injeção Sql.
FromSql não funciona com consulta completa. Exemplo, se você quiser incluir uma cláusula WHERE, ela será ignorada.
Alguns links:
Execução de consultas SQL brutas usando Entity Framework Core
Consultas SQL brutas
fonte
No Core 2.1, você pode fazer algo assim:
e definir o seu procedimento SQL, como:
Desta forma, o modelo de Ranks não será criado em seu BD.
Agora, em seu controlador / ação, você pode chamar:
Desta forma, você pode chamar procedimentos SQL brutos.
fonte
FromSql
parâmetros podem ser simplesmente passados sem criarSqlParameter
objeto:FromSql($"STORED_PROCEDURE {value1}, {value2}")
ouFromSql("STORED_PROCEDURE {0}, {1}", value1, value2)
(eles serão escapados).Você pode usar isso (em https://github.com/aspnet/EntityFrameworkCore/issues/1862#issuecomment-451671168 ):
E o uso:
fonte
Adicionar pacote Nuget - Microsoft.EntityFrameworkCore.Relational
Isso retornará os números da linha como um inteiro
Consulte - https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.relationaldatabasefacadeextensions.executesqlcommand?view=efcore-3.0
fonte
tente isto: (criar método de extensão)
Uso:
meu modelo: (não em
DbSet
):Nota: esta solução tem desempenho lento
fonte
Não visando diretamente o cenário do OP, mas como tenho lutado com isso, gostaria de abandonar esses ex. métodos que tornam mais fácil executar SQL bruto com
DbContext
:fonte
Usei Dapper para contornar essa restrição do Entity Framework Core.
está trabalhando com consulta sql ou procedimento armazenado com vários parâmetros. A propósito, é um pouco mais rápido (veja os testes de benchmark )
Dapper é fácil de aprender. Demorou 15 minutos para escrever e executar o procedimento armazenado com parâmetros. De qualquer forma, você pode usar EF e Dapper. Abaixo está um exemplo:
fonte
Você também pode usar QueryFirst . Como Dapper, isso está totalmente fora da EF. Ao contrário do Dapper (ou EF), você não precisa manter o POCO, você edita o SQL SQL em um ambiente real e ele é continuamente revalidado no banco de dados. Isenção de responsabilidade: sou o autor de QueryFirst.
fonte
Meu caso usou procedimento armazenado em vez de SQL bruto
Criou uma classe
Adicionado abaixo na minha
DbContext
aulaPara executar o procedimento armazenado:
fonte
Eu sei que é uma pergunta antiga, mas talvez ajude alguém a chamar procedimentos armazenados sem adicionar DTOs como DbSets.
https://stackoverflow.com/a/62058345/3300944
fonte
Esta solução se apóia fortemente na solução de @pius. Eu queria adicionar a opção de suporte a parâmetros de consulta para ajudar a mitigar a injeção de SQL e também queria torná-la uma extensão do DbContext DatabaseFacade para Entity Framework Core para torná-la um pouco mais integrada.
Primeiro crie uma nova classe com a extensão:
Observe acima que "T" é o tipo para o retorno e "P" é o tipo de seus parâmetros de consulta que irão variar dependendo se você está usando MySql, Sql, etc.
A seguir, mostraremos um exemplo. Estou usando o recurso MySql EF Core, então veremos como podemos usar a extensão genérica acima com esta implementação mais específica do MySql:
A consulta retornaria linhas como:
"Ford", "Explorer", "Ford Explorer"
"Tesla", "Model X", "Tesla Model X"
O título de exibição não é definido como uma coluna do banco de dados, então não faria parte do modelo EF Car por padrão. Gosto dessa abordagem como uma das muitas soluções possíveis. As outras respostas nesta página fazem referência a outras maneiras de resolver esse problema com o decorador [NotMapped], que dependendo do seu caso de uso pode ser a abordagem mais apropriada.
Observe que o código neste exemplo é obviamente mais detalhado do que precisa ser, mas achei que deixou o exemplo mais claro.
fonte
Com o Entity Framework 6 você pode executar algo como abaixo
Execute o comando Raw DQL SQl conforme abaixo:
fonte