Avec la suppression d'Entity Framework Core, dbData.Database.SqlQuery<SomeModel>
je ne trouve pas de solution pour créer une requête SQL brute pour ma requête de recherche en texte intégral qui renverra les données des tables ainsi que le classement.
La seule méthode que j'ai vue pour créer une requête SQL brute dans Entity Framework Core est via dbData.Product.FromSql("SQL SCRIPT");
ce qui n'est pas utile car je n'ai pas de DbSet qui mappera le rang que je renvoie dans la requête.
Des idées???
c#
entity-framework-core
David Harlow
la source
la source
Réponses:
Cela dépend si vous utilisez EF Core 2.1 ou EF Core 3 et les versions supérieures .
Si vous utilisez EF Core 2.1
Si vous utilisez EF Core 2.1 Release Candidate 1 disponible depuis le 7 mai 2018, vous pouvez profiter de la nouvelle fonctionnalité proposée qui est de type Requête.
Quel est le type de requête ?
Quand utiliser le type de requête?
Vous n'avez donc plus besoin de faire tous les hacks ou solutions de contournement proposés comme réponses à votre question. Suivez simplement ces étapes:
Vous avez d'abord défini une nouvelle propriété de type
DbQuery<T>
oùT
est le type de la classe qui portera les valeurs de colonne de votre requête SQL. Donc dans votreDbContext
vous aurez ceci:Ensuite, utilisez la
FromSql
méthode comme vous le faites avecDbSet<T>
:Notez également que les
DdContext
s sont des classes partielles , vous pouvez donc créer un ou plusieurs fichiers séparés pour organiser vos définitions «SQL DbQuery brutes» comme vous le souhaitez.Si vous utilisez EF Core 3.0 et les versions supérieures
Le type de requête est désormais appelé type d'entité sans clé . Comme indiqué ci-dessus, les types de requêtes ont été introduits dans EF Core 2.1. Si vous utilisez EF Core 3.0 ou une version supérieure, vous devez maintenant utiliser des types de tntity sans clé, car les types de requête sont désormais marqués comme obsolètes.
Nous avons toujours les mêmes scénarios que pour les types de requête pour savoir quand utiliser le type d'entité sans clé.
Donc, pour l'utiliser, vous devez d'abord marquer votre classe
SomeModel
avec[Keyless]
une annotation de données ou via une configuration fluide avec un.HasNoKey()
appel de méthode comme ci-dessous:Après cette configuration, vous pouvez utiliser l'une des méthodes expliquées ici pour exécuter votre requête SQL. Par exemple, vous pouvez utiliser celui-ci:
la source
bit
)?[NotMapped]
à laSomeModels
classe ne fonctionne pas pour moi. Ai-je manqué quelque chose?DbQuery
en faveur de l'utilisation uniquementDbSet
avec des types d'entités sans clé .modelBuilder.Entity<MyData>().HasNoKey().ToView(null);
@ Jean-Paul Je pense que cela résout votre problèmeEn me basant sur les autres réponses, j'ai écrit cet assistant qui accomplit la tâche, y compris un exemple d'utilisation:
Usage:
Je prévois de m'en débarrasser dès que le support intégré sera ajouté. Selon une déclaration d'Arthur Vickers de l'équipe EF Core, il s'agit d'une priorité élevée pour le post 2.0. Le problème est suivi ici .
la source
Dans EF Core, vous ne pouvez plus exécuter SQL brut "gratuit". Vous devez définir une classe POCO et une
DbSet
pour cette classe. Dans votre cas, vous devrez définir le rang :Comme il sera sûrement en lecture seule, il sera utile d'inclure l'
.AsNoTracking()
appel.EDIT - Changement de rupture dans EF Core 3.0:
DbQuery () est maintenant obsolète, à la place DbSet () doit être utilisé (à nouveau). Si vous avez une entité sans clé, c'est-à-dire qu'elle ne nécessite pas de clé primaire, vous pouvez utiliser la méthode HasNoKey () :
Plus d'informations peuvent être trouvées ici
la source
DbContext
pour inclure une nouvelle propriétéDbSet<Rank> Rank { get; set; }
. Quelles implications cela aura-t-il maintenant en référence à linq? C'est-à-dire que nous ne pourrons pas maintenant utiliser une instruction commeDBContext.Rank.Where(i => i.key == 1)
, et cette instruction n'aura-t-elle pas d'implémentation en SQL et échouera donc?Vous pouvez exécuter SQL brut dans EF Core - Ajoutez cette classe à votre projet. Cela vous permettra d'exécuter du SQL brut et d'obtenir les résultats bruts sans avoir à définir un POCO et un DBSet. Voir https://github.com/aspnet/EntityFramework/issues/1862#issuecomment-220787464 pour un exemple original.
Voici un exemple de son utilisation:
la source
Pour l'instant, jusqu'à ce qu'il y ait quelque chose de nouveau d'EFCore, j'utiliserais une commande et la mapperais manuellement
Essayez de SqlParameter pour éviter l'injection SQL.
FromSql ne fonctionne pas avec une requête complète. Exemple si vous souhaitez inclure une clause WHERE, elle sera ignorée.
Quelques liens:
Exécution de requêtes SQL brutes à l'aide d'Entity Framework Core
Requêtes SQL brutes
la source
Dans Core 2.1, vous pouvez faire quelque chose comme ceci:
puis définissez votre procédure SQL, comme:
De cette façon, le modèle Ranks ne sera pas créé dans votre base de données.
Maintenant, dans votre contrôleur / action, vous pouvez appeler:
De cette façon, vous pouvez appeler des procédures SQL brutes.
la source
FromSql
paramètres peuvent être simplement passés sans créer d'SqlParameter
objet:FromSql($"STORED_PROCEDURE {value1}, {value2}")
ouFromSql("STORED_PROCEDURE {0}, {1}", value1, value2)
(ils seront échappés).Vous pouvez utiliser ceci (à partir de https://github.com/aspnet/EntityFrameworkCore/issues/1862#issuecomment-451671168 ):
Et l'utilisation:
la source
Ajouter un package Nuget - Microsoft.EntityFrameworkCore.Relational
Cela renverra les numéros de ligne sous la forme d'un entier
Voir - https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.relationaldatabasefacadeextensions.executesqlcommand?view=efcore-3.0
la source
essayez ceci: (créer une méthode d'extension)
Usage:
mon modèle: (pas en
DbSet
):Remarque: cette solution a les performances lentes
la source
Ne ciblant pas directement le scénario du PO, mais depuis que j'ai du mal avec cela, j'aimerais abandonner ces ex. méthodes qui facilitent l'exécution du SQL brut avec
DbContext
:la source
J'ai utilisé Dapper pour contourner cette contrainte de Entity Framework Core.
fonctionne avec une requête SQL ou une procédure stockée avec plusieurs paramètres. Au fait c'est un peu plus rapide (voir les tests de référence )
Dapper est facile à apprendre. Il a fallu 15 minutes pour écrire et exécuter une procédure stockée avec des paramètres. Quoi qu'il en soit, vous pouvez utiliser à la fois EF et Dapper. Voici un exemple:
la source
Vous pouvez également utiliser QueryFirst . Comme Dapper, c'est totalement en dehors d'EF. Contrairement à Dapper (ou EF), vous n'avez pas besoin de maintenir le POCO, vous modifiez votre SQL SQL dans un environnement réel et il est continuellement revalidé par rapport à la base de données. Avertissement: je suis l'auteur de QueryFirst.
la source
Mon cas utilisait une procédure stockée au lieu du SQL brut
Créé une classe
Ajouté ci-dessous sur ma
DbContext
classePour exécuter la procédure stockée:
la source
Je sais que c'est une vieille question, mais peut-être que cela aide quelqu'un à appeler des procédures stockées sans ajouter de DTO en tant que DbSets.
https://stackoverflow.com/a/62058345/3300944
la source
Cette solution s'appuie fortement sur la solution de @pius. Je voulais ajouter l'option de prise en charge des paramètres de requête pour aider à atténuer l'injection SQL et je voulais également en faire une extension de DbContext DatabaseFacade pour Entity Framework Core pour le rendre un peu plus intégré.
Créez d'abord une nouvelle classe avec l'extension:
Notez dans ce qui précède que "T" est le type de retour et "P" est le type de vos paramètres de requête qui varieront selon que vous utilisez MySql, Sql, etc.
Ensuite, nous montrerons un exemple. J'utilise la fonctionnalité MySql EF Core, nous verrons donc comment nous pouvons utiliser l'extension générique ci-dessus avec cette implémentation MySql plus spécifique:
La requête renverrait des lignes telles que:
"Ford", "Explorer", "Ford Explorer"
"Tesla", "Model X", "Tesla Model X"
Le titre d'affichage n'est pas défini comme une colonne de base de données, il ne ferait donc pas partie du modèle EF Car par défaut. J'aime cette approche comme l'une des nombreuses solutions possibles. Les autres réponses de cette page font référence à d'autres moyens de résoudre ce problème avec le décorateur [NotMapped], qui selon votre cas d'utilisation pourrait être l'approche la plus appropriée.
Notez que le code de cet exemple est évidemment plus détaillé qu'il ne devrait l'être, mais j'ai pensé qu'il rendait l'exemple plus clair.
la source
Avec Entity Framework 6, vous pouvez exécuter quelque chose comme ci-dessous
Exécutez la commande Raw DQL SQl comme ci-dessous:
la source