Script
Name | Description | Last Modified Date | Download |
---|---|---|---|
CamlBuilder.cs | Wrapper over CAML queries. | 22/10/2014 | None |
CamlBuilder.cs
/// <summary> /// CAML Operations /// </summary> public enum CamlOperator { Contains, BeginsWith, Eq, Geq, Leq, Lt, Neq, DateRangesOverlap, IsNotNull, IsNull } /// <summary> /// CamlBuilder constructs CAML queries. Useful when needing dynamic generated CAML. /// Written by Tim Wheeler https://codemonkeysoftware.atlassian.net/wiki /// Version 2 /// </summary> /// <remarks> /// bool allWords = true; /// CamlBuilder builder = new CamlBuilder(); /// builder.Begin(allWords); //Uses an AND query /// builder.AddViewFields(new string[] {"Company", "Business Phone"});//Or leave empty to return all fields; /// builder.AddClause(CamlOperator.Contains, "Title", "My Text To Search For"); /// builder.AddOrderBy("Company",true); /// ... /// SPQuery query = new SPQuery(); /// query.Query = builder.Query; /// query.ViewFields = builder.ViewFields; /// ... /// Updates: /// Now contains ViewXml property when using with Client Object Model /// example: /// var builder = new CamlBuilder(); /// builder.Begin(true); /// builder.AddViewField("Title); /// builder.AddClause(CamlOperator.Eq, Fields.Title, "My Page Title"); /// var query = new CamlQuery(); /// query.ViewXml = builder.ViewXml; /// </remarks> public class CamlBuilder { #region Private Variables private ICollection<string> _camlClauses = new List<string>(); private Dictionary<string, bool> _orderByFields = new Dictionary<string, bool>(); private bool _requireAll; private StringBuilder _viewFields = new StringBuilder(); #endregion #region Public Query Properties (for retrieveing the query when ready) public string Query { get { return BuildQuery(); } } /// <summary> /// Used when dealing with Client Object Model /// </summary> public string ViewXml { get { return string.Format("<View><Query>{0}</Query><ViewFields>{1}</ViewFields>{2}</View>", TotalClauses == 0 ? string.Empty : Query, ViewFields, RowLimit.HasValue ? "<RowLimit>" + RowLimit.Value + "</RowLimit>" : string.Empty); } } public string ViewFields { get { return _viewFields.ToString(); } } public int TotalClauses { get { return _camlClauses.Count; } } public int? RowLimit { get; set; } #endregion #region public methods /// <summary> /// </summary> /// <param name="requireAll">Uses an AND operation between CAML pairs. Uses Or when false. All Words/Any Word</param> public void Begin(bool requireAll) { _camlClauses = new List<string>(); _requireAll = requireAll; _viewFields = new StringBuilder(); _orderByFields = new Dictionary<string, bool>(); } public void AddClause(CamlOperator operation, string fieldRef, int value) { AddClause(operation, fieldRef, value.ToString()); } public void AddClause(CamlOperator operation, string fieldRef) { _camlClauses.Add(string.Format("<{0}><FieldRef Name='{1}' /></{0}>", new[] { operation.ToString(), fieldRef })); } public void AddClause(CamlOperator operation, string fieldRef, string value) { if (!string.IsNullOrEmpty(value)) { _camlClauses.Add(string.Format("<{0}><FieldRef Name='{1}' /><Value Type='Text'>{2}</Value></{0}>", new[] { operation.ToString(), fieldRef, value })); } } public void AddClause(CamlOperator operation, string fieldRef, string value, string valueType) { if (!string.IsNullOrEmpty(value)) { _camlClauses.Add(string.Format("<{0}><FieldRef Name='{1}' /><Value Type='{2}'>{3}</Value></{0}>", new[] { operation.ToString(), fieldRef, valueType, value })); } } public void AddClauseWithLookupId(CamlOperator operation, string fieldRef, string value, string valueType) { if (!string.IsNullOrEmpty(value)) { _camlClauses.Add( string.Format("<{0}><FieldRef Name='{1}' LookupId='True' /><Value Type='{2}'>{3}</Value></{0}>", new[] { operation.ToString(), fieldRef, valueType, value })); } } public void AddViewField(string fieldRef) { _viewFields.AppendFormat("<FieldRef Name='{0}'/>", fieldRef); } public void AddViewFields(string[] fieldRefs) { foreach (string fieldRef in fieldRefs) { _viewFields.AppendFormat("<FieldRef Name='{0}'/>", fieldRef.Replace(" ", "_x0020_")); } } public void AddOrderBy(string fieldName, bool ascending) { _orderByFields.Add(fieldName, ascending); } #endregion #region Query Building private string BuildQuery() { var query = new StringBuilder(); int openOperators = 0; if (TotalClauses > 0) { query.Append("<Where>"); //When we have just one clause we can't use AND or OR. if (_camlClauses.Count > 1) { int totalCamlPairs = _camlClauses.Count - 1; //Math.DivRem(_CamlClauses.Count, 2, out remainder) + remainder; while (totalCamlPairs > 0) { query.Append(_requireAll ? "<And>" : "<Or>"); totalCamlPairs--; openOperators++; } } int clausesAdded = 0; foreach (string clause in _camlClauses) { query.Append(clause); clausesAdded++; if (clausesAdded > 1) { query.Append(_requireAll ? "</And>" : "</Or>"); openOperators--; } } query.Append("</Where>"); } if (_orderByFields.Count > 0) { query.Append("<OrderBy>"); foreach (var item in _orderByFields) { query.AppendFormat("<FieldRef Name='{0}' Ascending='{1}' />", item.Key, item.Value); } query.Append("</OrderBy>"); } return query.ToString(); } #endregion }