2011-06-01 32 views
27

我正在研究概念驗證代碼,以基於提供給我正在撰寫的高度特定搜索Web服務的關鍵字動態生成CAML。我沒有使用SharePoint提供的搜索Web服務來提供此證明。我已經這樣做了,我正在努力實現。從我所有的研究中,我無法找到一個我試圖實現的關鍵示例,即檢查多個字段的多個值。是的,我已經看到了我的答案,包括這個:Need help on building CAML Query帶嵌套AND和OR的多個字段的CAML查詢

這樣說,如果可能的話,如何在CAML中寫入下面的SQL類查詢?

SELECT FirstName, LastName, Description, Profile 
FROM SomeFakeTable 
WHERE (FirstName = 'John' OR LastName = 'John' OR Description = 'John' OR Profile='John') 
    AND (FirstName = 'Doe' OR LastName = 'Doe' OR Description = 'Doe' OR Profile='Doe') 
    AND (FirstName = '123' OR LastName = '123' OR Description = '123' OR Profile='123') 

回答

50

由於您不允許在一個條件組中放置兩個以上的條件(並且|),您必須創建一個額外的嵌套組(MSDN)。表達A AND B AND C看起來是這樣的:

<And> 
    A 
    <And> 
     B 
     C 
    </And> 
</And> 

你的SQL樣轉換爲CAML(希望匹配XML標籤;)):

<Where> 
    <And> 
     <Or> 
      <Eq> 
       <FieldRef Name='FirstName' /> 
       <Value Type='Text'>John</Value> 
      </Eq> 
      <Or> 
       <Eq> 
        <FieldRef Name='LastName' /> 
        <Value Type='Text'>John</Value> 
       </Eq> 
       <Eq> 
        <FieldRef Name='Profile' /> 
        <Value Type='Text'>John</Value> 
       </Eq> 
      </Or> 
     </Or> 
     <And>  
      <Or> 
       <Eq> 
        <FieldRef Name='FirstName' /> 
        <Value Type='Text'>Doe</Value> 
       </Eq> 
       <Or> 
        <Eq> 
         <FieldRef Name='LastName' /> 
         <Value Type='Text'>Doe</Value> 
        </Eq> 
        <Eq> 
         <FieldRef Name='Profile' /> 
         <Value Type='Text'>Doe</Value> 
        </Eq> 
       </Or> 
      </Or> 
      <Or> 
       <Eq> 
        <FieldRef Name='FirstName' /> 
        <Value Type='Text'>123</Value> 
       </Eq> 
       <Or> 
        <Eq> 
         <FieldRef Name='LastName' /> 
         <Value Type='Text'>123</Value> 
        </Eq> 
        <Eq> 
         <FieldRef Name='Profile' /> 
         <Value Type='Text'>123</Value> 
        </Eq> 
       </Or> 
      </Or> 
     </And> 
    </And> 
</Where> 
+0

謝謝,傑森!我回來看看我的問題,提供一個答案,因爲我自己想出來了。不過,我很高興看到您的答案與我的結果相符,非常感謝您花時間幫助我和其他SO用戶。 – Alban 2011-06-01 21:48:32

+0

感謝您的信息。您的示例XML提供了一種很好的方式來檢查嵌套的語法。我用它來提出這種方法生成[相當於In運算符](http://stackoverflow.com/questions/11198161/caml-in-operator-equivalent-for-sharepoint-services-3-sharepoint- 2007) – xr280xr 2012-06-25 22:19:43

0

您可以嘗試U2U查詢生成器http://www.u2u.net/res/Tools/CamlQueryBuilder.aspx可以使用他們的API U2U.SharePoint.CAML.Server.dll和U2U.SharePoint.CAML.Client.dll

我沒有用他們,但我肯定它會幫助你實現你的任務。

+13

,除非你知道,它可以提供所要求的結果,你不應該在這裏發佈的解決方案。使用U2U工具是非常節省時間的,但是您應該提供它生成的代碼的工作示例。 – 2012-07-18 18:38:30

0

此代碼將動態地嵌套爲您生成的表達條款。我有一個場景,其中「OR」的數目是未知的,所以我使用下面的。用法:

 private static void Main(string[] args) 
     { 
      var query = new PropertyString(@"<Query><Where>{{WhereClauses}}</Where></Query>"); 
      var whereClause = 
       new PropertyString(@"<Eq><FieldRef Name='ID'/><Value Type='Counter'>{{NestClauseValue}}</Value></Eq>"); 
      var andClause = new PropertyString("<Or>{{FirstExpression}}{{SecondExpression}}</Or>"); 

      string[] values = {"1", "2", "3", "4", "5", "6"}; 

      query["WhereClauses"] = NestEq(whereClause, andClause, values); 

      Console.WriteLine(query); 
     } 

而這裏的代碼:

private static string MakeExpression(PropertyString nestClause, string value) 
     { 
      var expr = nestClause.New(); 
      expr["NestClauseValue"] = value; 
      return expr.ToString(); 
     } 

     /// <summary> 
     /// Recursively nests the clause with the nesting expression, until nestClauseValue is empty. 
     /// </summary> 
     /// <param name="whereClause"> A property string in the following format: <Eq><FieldRef Name='Title'/><Value Type='Text'>{{NestClauseValue}}</Value></Eq>"; </param> 
     /// <param name="nestingExpression"> A property string in the following format: <And>{{FirstExpression}}{{SecondExpression}}</And> </param> 
     /// <param name="nestClauseValues">A string value which NestClauseValue will be filled in with.</param> 
     public static string NestEq(PropertyString whereClause, PropertyString nestingExpression, string[] nestClauseValues, int pos=0) 
     { 
      if (pos > nestClauseValues.Length) 
      { 
       return ""; 
      } 

      if (nestClauseValues.Length == 1) 
      { 
       return MakeExpression(whereClause, nestClauseValues[0]); 
      } 

      var expr = nestingExpression.New(); 
      if (pos == nestClauseValues.Length - 2) 
      { 
       expr["FirstExpression"] = MakeExpression(whereClause, nestClauseValues[pos]); 
       expr["SecondExpression"] = MakeExpression(whereClause, nestClauseValues[pos + 1]); 
       return expr.ToString(); 
      } 
      else 
      { 
       expr["FirstExpression"] = MakeExpression(whereClause, nestClauseValues[pos]); 
       expr["SecondExpression"] = NestEq(whereClause, nestingExpression, nestClauseValues, pos + 1); 
       return expr.ToString(); 
      } 
     } 






      public class PropertyString 
    { 
     private string _propStr; 

     public PropertyString New() 
     { 
      return new PropertyString(_propStr); 
     } 

     public PropertyString(string propStr) 
     { 
      _propStr = propStr; 
      _properties = new Dictionary<string, string>(); 
     } 

     private Dictionary<string, string> _properties; 
     public string this[string key] 
     { 
      get 
      { 
       return _properties.ContainsKey(key) ? _properties[key] : string.Empty; 
      } 
      set 
      { 
       if (_properties.ContainsKey(key)) 
       { 
        _properties[key] = value; 
       } 
       else 
       { 
        _properties.Add(key, value); 
       } 
      } 
     } 



     /// <summary> 
     /// Replaces properties in the format {{propertyName}} in the source string with values from KeyValuePairPropertiesDictionarysupplied dictionary.nce you've set a property it's replaced in the string and you 
     /// </summary> 
     /// <param name="originalStr"></param> 
     /// <param name="keyValuePairPropertiesDictionary"></param> 
     /// <returns></returns> 
     public override string ToString() 
     { 
      string modifiedStr = _propStr; 
      foreach (var keyvaluePair in _properties) 
      { 
       modifiedStr = modifiedStr.Replace("{{" + keyvaluePair.Key + "}}", keyvaluePair.Value); 
      } 

      return modifiedStr; 
     } 
    } 
+0

您是否搜索過嵌套或caml查詢限制?可能會導致此代碼出現問題。 – 2017-01-10 07:29:17