SQL IN equivalente in CAML
-
19-09-2019 - |
Domanda
C'è un modo "gentile" per creare una query CAML per SharePoint che fa qualcosa di simile?
SELECT *
FROM table
WHERE Id IN (3, 12, ...)
O sono bloccato con un incubo di nodi <Or>
nidificati?
EDIT:. Questa è stata la mia soluzione per generare i nodi <Or>
/// Simulates a SQL 'Where In' clause in CAML
/// </summary>
/// <param name="columnType">Specifies the data type for the value contained by the field.</param>
/// <returns>Nested 'Or' elements portion of CAML query</returns>
public static string CamlIn<T>(string internalFieldName, string columnType, T[] values)
{
XDocument doc = new XDocument();
XElement prev = null;
int index = 0;
while (index < values.Length)
{
XElement element =
new XElement("Or",
new XElement("Eq",
new XElement("FieldRef",
new XAttribute("Name", internalFieldName)),
new XElement("Value",
new XAttribute("Type", columnType),
values[index++].ToString())));
if (index == values.Length - 1)
{
element.AddFirst(
new XElement("Eq",
new XElement("FieldRef",
new XAttribute("Name", internalFieldName)),
new XElement("Value",
new XAttribute("Type", columnType),
values[index++].ToString())));
}
if (prev != null)
prev.AddFirst(element);
else
doc.Add(element);
prev = element;
}
return doc.ToString(SaveOptions.DisableFormatting);
}
Utilizzo:
int[] ids = new int[] { 1, 2, 4, 5 };
string query = string.Format("<Where>{0}</Where>", CamlIn("SomeColumn", "Number", ids));
Output:
<Where>
<Or>
<Or>
<Or>
<Eq>
<FieldRef Name=\"SomeColumn\" />
<Value Type=\"Number\">5</Value>
</Eq>
<Eq>
<FieldRef Name=\"SomeColumn\" />
<Value Type=\"Number\">4</Value>
</Eq>
</Or>
<Eq>
<FieldRef Name=\"SomeColumn\" />
<Value Type=\"Number\">2</Value>
</Eq>
</Or>
<Eq>
<FieldRef Name=\"SomeColumn\" />
<Value Type=\"Number\">1</Value>
</Eq>
</Or>
</Where>
fatta anche questo sovraccarico per il funzionamento con campo di ricerca un po 'più facile
/// <summary>
/// Simulates a SQL 'Where In' clause in CAML
/// </summary>
/// <param name="lookupId">Specify whether to use the Lookup column's Id or Value.</param>
/// <returns>Nested 'Or' elements portion of CAML query</returns>
public static string CamlIn<T>(string internalFieldName, bool lookupId, T[] values)
{
XDocument doc = new XDocument();
XElement prev = null;
int index = 0;
while (index < values.Length)
{
XElement element =
new XElement("Or",
new XElement("Eq",
new XElement("FieldRef",
new XAttribute("Name", internalFieldName),
lookupId ? new XAttribute("LookupId", "TRUE") : null),
new XElement("Value",
new XAttribute("Type", "Lookup"),
values[index++].ToString())));
if (index == values.Length - 1)
{
element.AddFirst(
new XElement("Eq",
new XElement("FieldRef",
new XAttribute("Name", internalFieldName),
lookupId ? new XAttribute("LookupId", "TRUE") : null),
new XElement("Value",
new XAttribute("Type", "Lookup"),
values[index++].ToString())));
}
if (prev != null)
prev.AddFirst(element);
else
doc.Add(element);
prev = element;
}
if (values.Length == 1)
{
XElement newRoot = doc.Descendants("Eq").Single();
doc.RemoveNodes();
doc.Add(newRoot);
}
return doc.ToString(SaveOptions.DisableFormatting);
}
Soluzione
NO, è necessario trattare con i tag annidati OR
; questi sono istruzioni di query supportati su CAML
CAML.NET può aiutare nella vostra ricerca.
Altri suggerimenti
Per coloro che utilizzano SharePoint 2010, c'è un elemento in disponibile:
http://msdn.microsoft.com/en-us/library/ ff625761.aspx
Ecco un esempio di lavoro:
SPQuery locationsQuery = new SPQuery();
locationsQuery.Query = string.Concat("<Where>",
"<In>",
"<FieldRef Name='ID' />",
"<Values>",
"<Value Type='Number'>6</Value>",
"<Value Type='Number'>7</Value>",
"<Value Type='Number'>8</Value>",
"</Values>",
"</In>",
"</Where>");
FullTextSqlQuery
E 'possibile cercare MOSS utilizzando le istruzioni SQL, utilizzando il FullTextSqlQuery classe. Non ho esperienza di utilizzo di questa classe personalmente. Questi articoli possono essere utili:
- http://blogit.create.pt/blogs/ricardocosta/archive/2007/06/15/How-to-use-FullTextSqlQuery-to-search-in-WSS.aspx
- http://www.dotnetmafia.com/blogs/dotnettipoftheday/archive/2008/03/06/how-to-use-the-moss-enterprise-search-fulltextsqlquery-class.aspx
YACAMLQT
In alternativa, c'è anche YACAMLQT (Ancora un altro strumento di query CAML) , che permette di creare SharePoint CAML query utilizzando una sintassi T-SQL.
LINQ to SharePoint
Se si è al passo con LINQ, poi il LINQ to SharePoint progetto fornisce uno strumento per interrogare elenchi di SharePoint utilizzando la sintassi LINQ. Si prega di notare, questo strumento è ancora in fase di alpha testing, quindi potrebbe non essere pronti per la produzione.
U2U CAML Query Builder
Se si sta lavorando con le query CAML, mi consiglia di utilizzare la U2U CAML Query Builder per SharePoint (2003 e 2007), strumento per costruire le query CAML. Lo strumento consente di costruire la vostra stringa di query, e di eseguirlo con l'elenco di destinazione, utilizzando un'interfaccia point-and-click, come illustrato di seguito.
(fonte: u2u.net )
di quanto sopra quattro metodi, posso consigliare il Query Builder U2U CAML, avendo usato quasi ogni giorno nel corso degli ultimi 6 mesi. Sembra anche essere lo strumento più utilizzato CAML nella comunità di SharePoint.
Nota, se si sta costruendo le query CAML nel codice, allora vi consiglio di dare un'occhiata alla CAML .NET progetto su CodePlex , che fornisce " una serie di .NET basato sul linguaggio strumenti per la creazione dinamica, riutilizzabili componenti di query CAML ".
Ho affrontato una cosa simile e alla fine ha dovuto creare un algoritmo ricorsivo per generare la nidificato o struttura. Ecco il mio algoritmo
var DynamicQuery = '<Query><Where>{{DYNAMICSTRING}}</Where></Query>';
var OneOR = '<Or><Eq><FieldRef Name="IMEI" /><Value Type="Text">{{SearchValue}}</Value></Eq>{{DYNAMICSTRING}}</Or>';
var TwoOr = '<Or><Eq><FieldRef Name="IMEI" /><Value Type="Text">{{SearchValue}}</Value></Eq><Eq><FieldRef Name="IMEI" /><Value Type="Text">{{SearchValue}}</Value></Eq></Or>';
var OnlyEq = '<Eq><FieldRef Name="IMEI" /><Value Type="Text">{{SearchValue}}</Value></Eq>';
function generateAdvancedInQuery(x){
if(x.length == 1)
return OnlyEq.replace('{{SearchValue}}',x[0]);
else if(x.length == 2)
return TwoOr.replace('{{SearchValue}}',x[0]).replace('{{SearchValue}}',x[1]);
else
return OneOR.replace('{{SearchValue}}',x[x.length-1]).replace('{{DYNAMICSTRING}}',generateAdvancedInQuery(x.splice(0,x.length-1) ) );
}
x = ['438753234098792','438753234098793','438753234098794','438753234098795','438753234098796','438753234098797','438753234098798'];
var Caml = DynamicQuery.replace('{{DYNAMICSTRING}}',generateAdvancedInQuery(x) )
Questo genera la query caml XML come
<Query>
<Where>
<Or>
<Eq>
<FieldRef Name="IMEI" />
<Value Type="Text">438753234098798</Value>
</Eq>
<Or>
<Eq>
<FieldRef Name="IMEI" />
<Value Type="Text">438753234098797</Value>
</Eq>
<Or>
<Eq>
<FieldRef Name="IMEI" />
<Value Type="Text">438753234098796</Value>
</Eq>
<Or>
<Eq>
<FieldRef Name="IMEI" />
<Value Type="Text">438753234098795</Value>
</Eq>
<Or>
<Eq>
<FieldRef Name="IMEI" />
<Value Type="Text">438753234098794</Value>
</Eq>
<Or>
<Eq>
<FieldRef Name="IMEI" />
<Value Type="Text">438753234098792</Value>
</Eq>
<Eq>
<FieldRef Name="IMEI" />
<Value Type="Text">438753234098793</Value>
</Eq>
</Or>
</Or>
</Or>
</Or>
</Or>
</Or>
</Where>
</Query>