Kann ich eine extension-Methode innerhalb einer LINQ-Abfrage?
Ich habe den folgenden code:
public QuestionDetail GetQuestionDetail(int questionId)
{
Question question = _questionsRepository.GetById(questionId);
QuestionDetail questionDetail = new QuestionDetail()
{
QuestionId = questionId,
Text = question.Text.FormatCode()
};
return questionDetail;
}
Ersetzt habe ich diese mit:
public QuestionDetail GetQuestionDetail(int questionId)
{
var questions = _questionsRepository
.GetAll()
.Include(q => q.Answers)
.Select(m => new QuestionDetail
{
QuestionId = m.QuestionId,
Text = m.Text.FormatCode()
})
.FirstOrDefault();
return questions;
}
Jetzt bekomme ich die folgende Fehlermeldung:
LINQ to Entities does not recognize the method 'System.String FormatCode(System.String)'
method, and this method cannot be translated into a store expression.
Hier mein FormatCode()
public static class CodeDisplay {
public static string FormatCode(this string content)
{
var data1 = content
.Split(new[] { "<pre>", "</pre>" }, StringSplitOptions.None);
var data2 = data1
.Select((s, index) =>
{
string s1 = index % 2 == 1 ? string.Format("{0}{2}{1}",
"<table class='code'>", "</table>", SplitJoin(s)) : s;
return s1;
});
var data3 = data2.Where(s => !string.IsNullOrEmpty(s));
var data4 = string.Join("\n", data3);
return data4;
}
private static string SplitJoin(string content)
{
IEnumerable<String> code =
content.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)
.Select((line, index) =>
string.Format("<tr><td>{0}</td><td><pre><code>{1}</code></pre></td></tr>\n",
(index + 1).ToString("D2"), HttpUtility.HtmlEncode(line)));
return string.Join("", code) + "\n";
}
}
- mögliche Duplikate von Verwendung von Benutzerdefinierten Erweiterung Methoden Innerhalb von Linq-Abfrage
- Mögliche Duplikate ja, aber ich habe nicht das Gefühl, die Antwort auf diese Frage ist sehr gut.
- Diese Frage ist spezifischer, so dass eine spezifische Antwort.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Kurze Antwort: ja, können Sie eine benutzerdefinierte Erweiterung Methode innerhalb einer LINQ-Abfrage - aber Sie können nicht verwenden Sie eine Erweiterung-Methode, die zugrunde liegenden Daten-provider nicht wissen, wie zum ausführen.
LINQ steht für Language-Integrated-Query, und ist ein sprachfeature von C#. Sie können jeden .NET-Methode in einer LINQ-Abfrage. LINQ als solche nicht über die zugrunde liegenden Daten zu speichern, die details, von denen ausgesetzt ist LINQ über die
IEnumerable<T>
oderIQueryable<T>
Schnittstellen. Wenn Sie Abfragen für ein Objekt, das implementiertIQueryable<T>
, wie ein Entity-Framework-Tabelle, die Schnittstelle stellt die zugrunde liegenden LINQ-provider, das weiß, über Abfragen in Entity Framework /SQL.Wenn Sie eine Methode in einer Abfrage .NET-Methode muss eine Umstellung der zugrunde liegenden Daten-provider, für diese zu arbeiten. Für LINQ-to-Objects (wo keine Datenbank beteiligt ist), ist diese Umwandlung trivial (dh. keine Konvertierung notwendig), so können Sie jedes beliebige Erweiterung Methoden. Für LINQ-to-SQL, LINQ-to-Entities (wie Sie mithilfe), die zugrunde liegenden Daten muss der Anbieter wissen, wie zu übersetzen, die CLR-Methode, um eine Darstellung der zugrunde liegenden Speicher, wie z.B. SQL. Dies ist die Aufgabe des LINQ-Anbieter.
Daher können Sie nicht verwenden Sie eine benutzerdefinierte Erweiterung Methode in Ihre LINQ-to-Entities-Abfrage. Für die, die arbeiten, die LINQ-provider müssten wissen, wie Sie stellen Ihre Methode in SQL, und er nicht weiß, dass.
Einen gemeinsamen Weg, dies zu erreichen sowieso, führen Sie die Abfrage in den zugrunde liegenden Datenprovider durch den Aufruf einer der eifrigen Methoden wie
ToArray()
oderToList()
, und dann eine weitere Verfeinerung der Abfragen nach, dass Sie mit Ihren benutzerdefinierten Methode. Denn das Ergebnis ist einfach CLR objects, LINQ-to-Objects verwendet wird, und Sie können Ihre benutzerdefinierten CLR-Methode. Just bewusst sein, dass dies möglicherweise Holen sich viele Ergebnisse aus der Datenbank. Für Ihr Beispiel, Sie sind nur Holen ein Ergebnis, das spielt also keine Rolle.Anwendung der erwähnten Muster würde der code wie folgt Aussehen:
Anstatt zu versuchen, führen Sie den FormatCode () - Methode in der LINQ to Entities, die nicht aufgrund der Tatsache, dass die ADO.NET Anbieter nicht weiß, wie übersetzen Sie es in SQL, können Sie die maximale Teil-der query, der ausgeführt werden kann, da LINQ to Entities-wie so:
Führen Sie dann die Methode der in-memory auf das Ergebnis, etwa so:
Könnten Sie versuchen,
Diese eintreten werden
question
im Speicher und können Sie anwenden das format, das Sie brauchen.