Wenn Entity Framework Core entfernt wird, dbData.Database.SqlQuery<SomeModel>
kann ich keine Lösung finden, um eine unformatierte SQL-Abfrage für meine Volltextsuchabfrage zu erstellen, die die Tabellendaten und auch den Rang zurückgibt.
Die einzige Methode, die ich gesehen habe, um eine unformatierte SQL-Abfrage in Entity Framework Core zu erstellen, ist eine, dbData.Product.FromSql("SQL SCRIPT");
die nicht nützlich ist, da ich kein DbSet habe, das den Rang abbildet, den ich in der Abfrage zurückgebe.
Irgendwelche Ideen???
c#
entity-framework-core
David Harlow
quelle
quelle
Antworten:
Dies hängt davon ab, ob Sie EF Core 2.1 oder EF Core 3 und höhere Versionen verwenden .
Wenn Sie EF Core 2.1 verwenden
Wenn Sie EF Core 2.1 Release Candidate 1 verwenden, das seit dem 7. Mai 2018 verfügbar ist, können Sie die vorgeschlagene neue Funktion vom Typ Abfrage nutzen.
Was ist der Abfragetyp ?
Wann wird der Abfragetyp verwendet?
Sie müssen also nicht mehr alle Hacks oder Workarounds ausführen, die als Antwort auf Ihre Frage vorgeschlagen wurden. Befolgen Sie einfach diese Schritte:
Zuerst haben Sie eine neue Eigenschaft vom Typ definiert,
DbQuery<T>
wobeiT
es sich um den Typ der Klasse handelt, die die Spaltenwerte Ihrer SQL-Abfrage enthält. Also in deinemDbContext
hast du folgendes:Verwenden
FromSql
Sie zweitens die Methode wie folgtDbSet<T>
:Beachten Sie auch , dass
DdContext
s sind Teil-Klassen , so dass Sie eine oder mehrere separate Dateien erstellen können Ihre ‚raw SQL dbquery‘ Definitionen , wie am besten zu Ihnen passt zu organisieren.Wenn Sie EF Core 3.0 und höhere Versionen verwenden
Der Abfragetyp wird jetzt als schlüsselloser Entitätstyp bezeichnet . Wie oben erwähnt, wurden Abfragetypen in EF Core 2.1 eingeführt. Wenn Sie EF Core 3.0 oder eine höhere Version verwenden, sollten Sie jetzt die Verwendung von Keyless-Tntity-Typen in Betracht ziehen, da Abfragetypen jetzt als veraltet markiert sind.
Wir haben immer noch die gleichen Szenarien wie für Abfragetypen, wenn ein schlüsselloser Entitätstyp verwendet werden soll.
Um es zu verwenden, müssen Sie Ihre Klasse zuerst
SomeModel
mit[Keyless]
Datenanmerkungen oder durch fließende Konfiguration mit einem.HasNoKey()
Methodenaufruf wie folgt markieren :Nach dieser Konfiguration können Sie eine der hier erläuterten Methoden verwenden, um Ihre SQL-Abfrage auszuführen. Zum Beispiel können Sie dieses verwenden:
quelle
bit
)?[NotMapped]
zurSomeModels
Klasse funktioniert bei mir nicht. Habe ich etwas vergessen?DbQuery
nurDbSet
für schlüssellose Entitätstypen verwendet .modelBuilder.Entity<MyData>().HasNoKey().ToView(null);
@ Jean-Paul Ich denke, das löst dein ProblemAufbauend auf den anderen Antworten habe ich diesen Helfer geschrieben, der die Aufgabe erfüllt, einschließlich der Verwendung von Beispielen:
Verwendung:
Ich habe vor, es loszuwerden, sobald die integrierte Unterstützung hinzugefügt wird. Laut einer Aussage von Arthur Vickers vom EF Core-Team hat dies für Post 2.0 eine hohe Priorität. Das Problem wird hier verfolgt .
quelle
In EF Core können Sie "free" raw sql nicht mehr ausführen. Sie müssen eine POCO-Klasse und eine
DbSet
für diese Klasse definieren. In Ihrem Fall müssen Sie Rang definieren :Da es sicherlich nur lesbar sein wird, ist es nützlich, den
.AsNoTracking()
Anruf einzuschließen .EDIT - Breaking Change in EF Core 3.0:
DbQuery () ist jetzt veraltet, stattdessen sollte DbSet () (erneut) verwendet werden. Wenn Sie eine schlüssellose Entität haben, dh keinen Primärschlüssel benötigen, können Sie die HasNoKey () -Methode verwenden:
Weitere Informationen finden Sie hier
quelle
DbContext
, um eine neue Eigenschaft aufzunehmenDbSet<Rank> Rank { get; set; }
. Welche Auswirkungen wird dies nun in Bezug auf linq haben? Dh können wir jetzt keine Anweisung wie verwendenDBContext.Rank.Where(i => i.key == 1)
, und wird diese Anweisung nicht in SQL implementiert und schlägt daher fehl?Sie können Raw-SQL in EF Core ausführen - Fügen Sie diese Klasse Ihrem Projekt hinzu. Auf diese Weise können Sie unformatiertes SQL ausführen und die rohen Ergebnisse abrufen, ohne ein POCO und ein DBSet definieren zu müssen. Ein Originalbeispiel finden Sie unter https://github.com/aspnet/EntityFramework/issues/1862#issuecomment-220787464 .
Hier ist ein Beispiel für die Verwendung:
quelle
Bis es etwas Neues von EFCore gibt, würde ich einen Befehl verwenden und ihn manuell zuordnen
Versuchen Sie, SqlParameter zu verwenden, um eine SQL-Injektion zu vermeiden.
FromSql funktioniert nicht mit vollständiger Abfrage. Beispiel: Wenn Sie eine WHERE-Klausel einfügen möchten, wird diese ignoriert.
Einige Links:
Ausführen von Raw SQL-Abfragen mit Entity Framework Core
Rohe SQL-Abfragen
quelle
In Core 2.1 können Sie Folgendes tun:
und definieren Sie dann Ihre SQL-Prozedur wie:
Auf diese Weise wird in Ihrer Datenbank kein Ranks-Modell erstellt.
Jetzt können Sie in Ihrem Controller / Ihrer Aktion Folgendes aufrufen:
Auf diese Weise können Sie Raw SQL-Prozeduren aufrufen.
quelle
FromSql
Parameter können einfach übergeben werden, ohne einSqlParameter
Objekt zu erstellen :FromSql($"STORED_PROCEDURE {value1}, {value2}")
oderFromSql("STORED_PROCEDURE {0}, {1}", value1, value2)
(sie werden maskiert ).Sie können dies verwenden (von https://github.com/aspnet/EntityFrameworkCore/issues/1862#issuecomment-451671168 ):
Und die Verwendung:
quelle
Nuget-Paket hinzufügen - Microsoft.EntityFrameworkCore.Relational
Dies gibt die Zeilennummern als int zurück
Siehe - https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.relationaldatabasefacadeextensions.executesqlcommand?view=efcore-3.0
quelle
Versuchen Sie Folgendes: (Erweiterungsmethode erstellen)
Verwendung:
mein Modell: (nicht in
DbSet
):Hinweis: Diese Lösung weist eine langsame Leistung auf
quelle
Ich ziele nicht direkt auf das OP-Szenario ab, aber da ich damit zu kämpfen habe, möchte ich diese Ex fallen lassen. Methoden, die es einfacher machen, Raw SQL auszuführen mit
DbContext
:quelle
Ich habe Dapper verwendet , um diese Einschränkung des Entity Framework Core zu umgehen.
arbeitet entweder mit einer SQL-Abfrage oder einer gespeicherten Prozedur mit mehreren Parametern. Übrigens ist es etwas schneller (siehe Benchmark-Tests )
Dapper ist leicht zu lernen. Das Schreiben und Ausführen der gespeicherten Prozedur mit Parametern dauerte 15 Minuten. Auf jeden Fall können Sie sowohl EF als auch Dapper verwenden. Unten ist ein Beispiel:
quelle
Sie können auch QueryFirst verwenden . Wie Dapper liegt dies völlig außerhalb von EF. Im Gegensatz zu Dapper (oder EF) müssen Sie den POCO nicht warten, Sie bearbeiten Ihr SQL-SQL in einer realen Umgebung und es wird gegenüber der Datenbank kontinuierlich neu validiert. Haftungsausschluss: Ich bin der Autor von QueryFirst.
quelle
In meinem Fall wurde eine gespeicherte Prozedur anstelle von unformatiertem SQL verwendet
Erstellt eine Klasse
Unten in meiner
DbContext
Klasse hinzugefügtSo führen Sie die gespeicherte Prozedur aus:
quelle
Ich weiß, dass es eine alte Frage ist, aber vielleicht hilft es jemandem, gespeicherte Prozeduren aufzurufen, ohne DTOs als DbSets hinzuzufügen.
https://stackoverflow.com/a/62058345/3300944
quelle
Diese Lösung stützt sich stark auf die Lösung von @pius. Ich wollte die Option zur Unterstützung von Abfrageparametern hinzufügen, um die SQL-Injection zu verringern, und ich wollte es auch zu einer Erweiterung des DbContext DatabaseFacade für Entity Framework Core machen, um es ein wenig integrierter zu machen.
Erstellen Sie zunächst eine neue Klasse mit der Erweiterung:
Beachten Sie oben, dass "T" der Typ für die Rückgabe ist und "P" der Typ Ihrer Abfrageparameter ist, der abhängig davon variiert, ob Sie MySql, Sql usw. verwenden.
Als nächstes zeigen wir ein Beispiel. Ich verwende die MySql EF Core-Funktion, daher werden wir sehen, wie wir die oben genannte generische Erweiterung mit dieser spezifischeren MySql-Implementierung verwenden können:
Die Abfrage würde Zeilen wie
"Ford", "Explorer", "Ford Explorer",
"Tesla", "Modell X", "Tesla-Modell X" zurückgeben.
Der Anzeigetitel ist nicht als Datenbankspalte definiert, sodass er standardmäßig nicht Teil des EF Car-Modells ist. Ich mag diesen Ansatz als eine von vielen möglichen Lösungen. Die anderen Antworten auf dieser Seite verweisen auf andere Möglichkeiten, um dieses Problem mit dem Dekorator [NotMapped] zu beheben. Dies kann je nach Anwendungsfall der geeignetere Ansatz sein.
Beachten Sie, dass der Code in diesem Beispiel offensichtlich ausführlicher ist, als er sein muss, aber ich dachte, er macht das Beispiel klarer.
quelle
Mit Entity Framework 6 können Sie Folgendes ausführen
Führen Sie den Raw DQL SQl-Befehl wie folgt aus:
quelle