Pages

Monday 5 September 2011

Query Data Using CAML

You can use CAML to do the following:

Modify parameters to transport complex data
Define the body of SOAP messages to transport data using web services
Configure SharePoint for usage or deployment
Add specific behavior to features
SharePoint utilizes many XML files to define behavior and content. Most of these files use CAML as the dialect to express SharePoint-specific settings. In this section, we examine more closely the usage of CAML to query the data store. CAML is defined in several schemas. When you first attempt to understand CAML, it looks like an amalgam of many different dialects. However, it’s simply a collection of schemas that make CAML powerful enough for both data schema definition and data retrieval.

Using CAML to Retrieve Data

The Query schema is well documented, and numerous examples are available. However, the first time you try it, you’ll discover it’s not self-explanatory. All queries must be executed against a list. You need a reference to either an SPList or SPView object, which accepts a CAML query and can run it. The following examples demonstrate the bare bones of the technique.
The basic way to query data from SharePoint lists is to use queries constructed with CAML. The next code snippet shows a simple CAML query to fetch all items from a SharePoint list called Books whose Publisher is Apress .

public IEnumerable<SPListItem> GetBooksFromAPress()
{
SPList list = SPContext.Current.Web.Lists["Books"];
SPQuery query = new SPQuery();
query.Query = @"<Where>
<Eq>
<FieldRef Name='Publisher' />
<Value Type='Text'>Apress</Value>
</Eq>
</Where>";
IEnumerable<SPListItem> books = list.GetItems(query).OfType<SPListItem>();
return books;
}

In this example, the list is obtained from the current SPWeb instance. A new SPQuery object is instantiated to contain the query. The query is written as an XML string fragment.
With CAML, you can easily build your own custom queries, including conditions (Where) and logical operators (AND, OR) in XML format. Internally, SharePoint translates the CAML query into a SQL query to retrieve the data from the SharePoint content database.

How to Create a CAML Query

You can use LINQ to XML and the XElement type to create a query:

SPQuery queryl = new SPQuery();
queryl.Query = new XElement("Where",
new XElement("Eq",
new XElement("FieldRef", new XAttribute("Name", "Company")),
new XElement("Value", new XAttribute("Type", "Text")))) .ToString();

While this approach takes care of closing tags correctly and will always create valid XML, it does not seem easier. The CAML keywords are strings, and hence they can suffer from typing errors. You might consider using constants to predefine such keywords:

const string WHERE = "Where";
const string EQ = "Eq";
const string FIELDREF = "FieldRef";
const string VALUE = "Value";
const string NAME = "Name";
const string TYPE = "Type";
SPQuery queryc = new SPQuery();
queryc.Query = new XElement(WHERE,
new XElement(EQ,
new XElement(FIELDREF, new XAttribute(NAME, "Company")),
new XElement(VALUE, new XAttribute(TYPE, "Text"))))
.ToString();

That’s indeed safe and compact, but it’s still a manually built query. To overcome the manual construction of CAML queries, there are some useful implementations of CAML query builders that support creating a CAML query in a safe manner. To demonstrate this, check out an example using CAML.NET from John Holliday, which is a free project hosted on CodePlex (www.codeplex.com/camldotnet). Here is how to use it:

public IEnumerable<SPListItem> GetBooksFromAPress2()
{
SPList list = SPContext.Current.Web.Lists["Books"];
SPQuery query = new SPQuery();
query.Query = CAML.Where(
CAML.Eq(
CAML.FieldRef("Publisher"),
CAML.Value("APress")
)
);
IEnumerable<SPListItem> books = list.GetItems(query).OfType<SPListItem>();
return books;
}

If you need to use many manually constructed CAML queries, we strongly recommend using a CAML query builder such as CAML.NET. This is the least error-prone and most efficient method.

No comments:

Post a Comment

Popular Posts