Frage

ich eine Dokumentenklasse haben, die eine Liste von „Tags“ enthält. So etwas wie:

class Item {
  string Name { get; set; }
  List<string> Tags {get; set;}
}

Nun würde Ich mag eine Abfrage für RavenDB schaffen, dass die Hände mich alle Elemente durch eine Liste von Tags gefiltert. Wenn Entity Framework Ich schaffte es mit diesem, wie dies etwas zu tun:

var query = GetQueryable();
foreach (var tag in tags)
{
   query = query.Where(i => i.Tags.Contains(tag));
}

Dies ist jedoch an der Arbeit scheint nicht mit RavenDB, höchstwahrscheinlich, weil Enthält nicht unterstützt wird .. Ich habe Umschreiben es auch versucht, mit Any, (Where(i => i.Tags.Any(t=>t == tag))), aber das gibt mir eine seltsame Ausnahme:

Unable to cast object of type
'System.Linq.Expressions.PrimitiveParameterExpression`1[System.String]'
to type 'System.Linq.Expressions.MemberExpression

Jede gute Ideen? Bin ich tun, diese völlig falsch?

War es hilfreich?

Lösung

enthält, ist in der Tat noch nicht unterstützt (Vielleicht sollte es sein, aber das ist eine ganz andere Sache - wir wirklich nur die Unterstützung für verschiedene Betreiber, wenn seine gebeten)

Wie für mehrere Abfragen gegen Alle, ich nehme an, Sie versuchen, dynamische Daten zu tun, und Sie wollen so etwas wie

erreichen
"X OR Y OR Z"

Das ist eine schwierige Sache, und die LINQ-Anbieter standardmäßig werden diese mehr WHERE-Klauseln mit AND, so dass Ihr Beispiel sieht aus wie

aggregieren
"X AND Y AND Z"

Was wird natürlich nie der Fall sein.

Ihre beste Option für diese ist auf die Lucene-Abfrage Dropdown (zumindest vorerst) und etwas tun, wie folgt aus:

var results = s.Advanced.LuceneQuery<Item>()
                   .Where(string.Format("Tags,:({0})", string.Join(" OR ", tags))); 

Sinn?

Die Abfrage oben wie etwas aussehen wird

"Tags,:(X OR Y OR Z)"

Hinweis: "Schlagwörter", informiert RavenDB dass Stichworte ein Array

Okay, [Bearbeiten]!

Der einfachste Weg zu bekommen, was Sie eigentlich wollen ist etwas in dieser Richtung zu tun

                new IndexDefinition<Item, Item>()
                {
                    Map = docs => from doc in docs
                                  select new
                                  {
                                      Tags = doc.Tags
                                  },
                    Indexes = {{ x => x.Tags, FieldIndexing.Analyzed }}
                }.ToIndexDefinition(store.Conventions));

Dann Abfrage für Ihre ands, können Sie etwas tun:

                var results = s.Advanced.LuceneQuery<Item, WhateverYouCalledThatIndex>()
                   .Where(string.Format("Tags:({0})", string.Join(" AND ", tags)));

Nun, die Dinge zu beachten

       Tags = doc.Tags

Wird diese gesamte Array in einen riesigen Klecks serialisiert, da es nur Zeichenfolge ist, die für dieses Beispiel funktioniert.

Ich bin auf bessere Möglichkeiten, dies auszudrücken suche, ist es unwahrscheinlich, dass wir dies mit einer LINQ-ish Art und Weise zu tun, kommen würden, da es nicht wirklich sehr gut über abbildet - aber es ist eine Antwort, die funktioniert:)

Ich glaube, ich würde ganz gerne in der Lage sein, zumindest tun

  Map = docs => from doc in docs
                                  select new
                                  {
                                      Tags = String.Join(" ", doc.Tags)
                                  },

(Dies wird nicht so funktionieren sie nicht versuchen), aber es ist ein bisschen mehr explizit über das, was Sie erreichen wollen.

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