2016-09-01 3 views
1

Ich versuche, eine mathematische Funktion zu SQL Server senden mit Entity Framework 6.Wie Math-Funktionen für SQL Server mit Entity Framework 6

Ich habe eine einfache Abfrage senden:

using(var db = databaseContext) 
{ 
    var query = db.Foo.Select(x => Math.Sin(x.bar)); 
} 

Doch diese gibt mir eine Ausnahme.

Eine Ausnahme vom Typ 'System.NotSupportedException' aufgetreten in EntityFramework.dll wurde aber in Benutzercode

Zusätzliche Informationen nicht behandelt: LINQ to Entities ist die Methode nicht erkennen ‚Double Sin (Doppel) 'Methode, und diese Methode kann nicht in ein Store-Ausdruck übersetzt werden.

Das Problem ist, dass Entity Framework nicht wissen, wie man Math.sin in ein Sql Server-Äquivalent übersetzt. Gibt es noch andere Klassen, die ich benutzen kann?

+0

Verwenden Sie 'Math.Sin' auf der Codepage – Fabio

+0

Ich kann dies nicht in der Code-Seite tun. Das obige Beispiel ist ein Spielzeugbeispiel, aber in Wirklichkeit mache ich das auf einer sehr großen Datenbank mit Millionen von Zeilen. Obendrein muss ich in der Lage sein, nach dieser mathematischen Funktion zu sortieren und meine Ergebnisse zu pagen. Dies auf der Codepage zu tun, ist keine Option. – Soto

+0

@Soto bitte die richtige Antwort als "richtig" markieren, da eine andere Antwort mehr Upvotes hat - andere Benutzer mit dem gleichen Problem können dann zuerst die richtige Antwort sehen. Wie Sie sehen, wird die Antwort mit der code-basierten Lösung immer noch upvotes, was Performance kostet! Würdest du bitte ?! –

Antwort

4

i würde zuerst die Daten aus der DB laden und

using(var db = databaseContext) 
{ 
    var listofFoo= db.Foo.toList(); 
    var listofFooSin = listofFoo.Select(x => Math.Sin(x.bar)); 
} 
+0

Dieser Ansatz führt die Ergebnisse zweimal durch. – Fabio

+0

wird es nicht? Oder durchläuft 'ToList()' alle Elemente? überprüfe den EF-Code was "ToList" wirklich macht. Es ist opensource :) –

+0

Ich kann dies nicht in der Code-Seite tun.Das obige Beispiel ist ein Spielzeugbeispiel, aber in Wirklichkeit mache ich das auf einer sehr großen Datenbank mit Millionen von Zeilen. Obendrein muss ich in der Lage sein, nach dieser mathematischen Funktion zu sortieren und meine Ergebnisse zu pagen. Dies auf der Codepage zu tun, ist keine Option. – Soto

4

Eine Tonne MSSQL spezifischen Funktionen in Speichern, wie Berechnungen werden als statische Methoden in der Klasse ausgesetzt System.Data.Objects.SqlClient.SqlFunctions - aber nicht alle. Für Sin können Sie SqlFunctions.Sin verwenden und müssen nicht linq zum Objekt verwenden. der Standardwert Sin ist keine unterstützte Funktion in EF

+0

Das hat für mich funktioniert! Vielen Dank. – Soto

+0

Ich bin mir nicht sicher, ob Sie das beabsichtigt haben oder Ihre Antwort ist nur verwirrend formuliert, aber ['SqlFunctions.Sin'] (https://msdn.microsoft.com/library/dd466178) existiert sicherlich. LINQ to Objects muss nicht verwendet werden. –

+0

Ja, ich stimme zu. Du hast die korrekte Funktion 'SqlFunctions' gegeben, aber dann sagst du, dass Sünde nicht unterstützt wird ... aber das ist es. – Soto

1

Ihr Objekt ist noch nicht REALISED und kann daher keine komplexen Funktionen ausführen. Dies ist ähnlich bei der Verwendung von Erweiterungsmethoden und anderen Dingen. Die Magie des Hinzufügens einer 'ToList()' in vielen Dingen mit EntityFramework wird es realisieren und als solches in der Lage sein, mehr Dinge zu tun. Verwenden Sie im Zweifelsfall mit Entity eine 'ToList()'. Das Problem ist, dass die Objekte nicht realisiert Fülling, wenn Sie etwas tun, ähnlich wie:

'context.(object).Select(x => (docomplexThing(x))' 

Entity hat einige Grundeigenschaften und Operationen wie equalitative Operationen und Lambda-Funktionen kann es tun. Es kann keine Schwerlastmethoden ausführen, bis das Objekt in ein realeres Objekt im Speicher umgewandelt oder auf etwas projiziert wird. ToList erreicht dies. Es sind nicht nur mathematische Operationen, sondern auch Verschlüsselung und maßgeschneiderte Erweiterungsmethoden. Manchmal werden sie in Fällen arbeiten, aber die meiste Zeit nicht. Ich denke immer daran wie die ADO.NET-Schichten, wo Sie eine getrennte und eine verbundene Ebene haben. Der Kontext und das Ergreifen von Dingen daraus ist verbunden und als solches gibt es nicht viele Optionen, sobald es durch oder projiziert ist, hast du freie Hand, um auf Dinge loszugehen.

static void Main(string[] args) 
{ 
    using (var context = new TesterEntities()) 
    { 
    var items = context.tePersons.ToList().Select(x => Math.Sin(x.PersonId));   
    } 

    Console.ReadLine(); 
} 
Verwandte Themen