Frage

Ich habe die folgende Linq -Abfrage:

var aKeyword = "ACT";
var results = from a in db.Activities
              where a.Keywords.Split(',').Contains(aKeyword) == true
              select a;

Keywords ist ein Komma -Abgrenzungsfeld.

Jedes Mal, wenn ich diese Abfrage ausführe, erhalte ich den folgenden Fehler:

"LINQ zu Entitäten erkennt die Methode 'boolean enthält [String] (System.Collections.generic.IenumerableAn`1 [System.String], System.String)' Methode, und diese Methode kann nicht in einen Speicherausdruck übersetzt werden."

Was ist die Alternative für das, was ich versuche zu tun?

War es hilfreich?

Lösung

Als Reaktion auf Ihre Leistungsüberlegungen zu einem großen Datensatz:

Sie werden nicht indexierte Wildcard -String -Matching für den Client durchführen. Ja, es wird einen Leistungsverlust geben.

Gibt es einen Grund, warum Sie mehrere Schlüsselwörter in einem Tabellenfeld haben? Sie können dies normalisieren, um eine Aktivitätskeyword -Tabelle zu haben, in der Sie für jede Aktivität eine Reihe von Schlüsselwortdatensätzen haben.

Aktivitäten (Activity_id, ... / * Entfernen von Schlüsselwörtern * /) ---> ActivityKeywords (Activity_id, Keyword_id) ---> Schlüsselwörter (Keyword_id, Wert)

Schauen Sie sich das nicht erste normale Formular an: http://en.wikipedia.org/wiki/database_normalization

Bearbeiten: Auch wenn Sie sich an die eine Spalte halten, gibt es eine Möglichkeit, alles Serverside zu machen (wenn Sie eine strenge Syntax haben: 'Keyword1, Keyword2, ..., Keywordn'):

var aKeyword = "ACT";
var results = (from a in db.Activities
              where a.Keywords.Contains("," + aKeyword) || a.Keywords.Contains(aKeyword + ",")
              select a;

Andere Tipps

Ihr Problem ist, dass Linq-to-Eventite alles, was Sie ihm geben, in SQL übersetzen müssen, um sie an die Datenbank zu senden.

Wenn dies wirklich das ist, was Sie tun müssen, müssen Sie Linq-to-Intitäten dazu zwingen, alle Daten und Linq-to-Objects zurückzuziehen, um den Zustand zu bewerten.

Ex:

var aKeyword = "ACT";
var results = from a in db.Activities.ToList()
              where a.Keywords.Split(',').Contains(aKeyword) == true
              select a;

Beachten Sie jedoch, dass dies alle Objekte aus dem Aktivitätentisch zurückzieht. Eine Alternative kann darin bestehen, dass die DB ein bisschen einen Anfangsfilter durchführen und den Rest des Weges danach filtern:

var aKeyword = "ACT";
var results = (from a in db.Activities
              where a.Keywords.Contains(aKeyword)
              select a).ToList().Where(a => a.KeyWords.Split(',').Contains(aKeyword));

Dadurch können Linq-to-Is-Inities den von ihm verstandenen Filter durchführen (String.containes wird zu einer ähnlichen Abfrage), die einige der Daten abfilter . Der Tolist () Call erzwingt Linq-to-Is-I-Abgaben, die Abfrage auszuführen und die Objekte zu erstellen, sodass Linq-to-Objects der Motor sein kann, der den zweiten Teil der Abfrage durchführt.

Meine Vermutung ist die Art und Weise, wie Sie Split anrufen. Es sollte ein Array dauern. Vielleicht gibt es einen weiteren Split in Linq, der Ihnen einen ungewöhnlichen Fehler findet und gibt:

Dies funktioniert für LINQ zu Objekten:

 var dataStore = new List<string>
                    {
                        "foo,bar,zoo",
                        "yelp,foo",
                        "fred",
                        ""
                    };
 var results = from a in dataStore
               where a.Split(new[] {','}).Contains("foo")
               select a;

 foreach (var result in results)
 {
     Console.WriteLine("Match: {0}", result);
 }

Gibt Folgendes aus:

Match: foo,bar,zoo
Match: yelp,foo

Benötigen Sie eigentlich überhaupt die Trennung? a.Contains("foo") Kann für Sie ausreichen (es sei denn, Sie möchten nicht schlagen wollen foobar).

Du möchtest vielleicht Sehen Sie sich diese Frage zu L2E und .Contains an für eine Lösung, die effizienter sein sollte als bei einem Superset vor dem Filtern der Client -Seite.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top