【问题标题】:Sharepoint dynamic caml query problem?Sharepoint动态caml查询问题?
【发布时间】:2010-12-31 10:19:24
【问题描述】:

我想根据查询字符串进行动态caml查询,我用例子来解释一下

我的查询字符串可以是任何东西

?cat=ABC&cat=ABD&cat=ABE...
?Cat=ABC
?Cat=ABC&cat=ABL

所以没有。现在问题开始了,可以是任何东西

我想根据这个查询字符串查询我的共享点列表

if (HttpContext.Current.Request.QueryString["cat"] != null)
        {
            string _cat = HttpContext.Current.Request.QueryString["cat"].ToString();
        }

这样我的字符串就包含了所有的查询

string _cat=ABC,AD,....all.

我想根据这些查询字符串和“AND”查询我的共享点列表

where title=ABC and title=AD ....

如果只有一个查询字符串,那么只有 其中title=ABC....所以我希望我的查询字符串应该是动态的.... 知道如何实现这一目标吗??

【问题讨论】:

    标签: c# sharepoint caml


    【解决方案1】:

    假设您正在谈论多选选择字段...很可能您每次都必须创建查询。

    您的代码将需要确定传入的类别数量,然后生成 CAML。例如,如果只传递了 ABC,您的查询将是(注意没有 <And> 标签):

    <Where>
      <Eq>
        <FieldRef Name='Category'/>
        <Value Type='Choice'>ABC</Value>
      </Eq>
    </Where>
    

    但是,如果您通过 QueryString 传入三个选项:ABC、ABD 和 ABE,您会得到(注意 &lt;And&gt; 标记围绕每两个组):

    <Where>
      <And>
        <And>
          <Eq>
            <FieldRef Name='Category'/>
            <Value Type='Choice'>ABC</Value>
          </Eq>
          <Eq>
            <FieldRef Name='Category'/>
            <Value Type='Choice'>ABD</Value>
          </Eq>
        </And>
        <Eq>
          <FieldRef Name='Category'/>
          <Value Type='Choice'>ABE</Value>
        </Eq>
      </And>
    </Where>
    

    编辑:

    static void Main(string[] args)
    {
        try
        {
            string[] parameters = { "ABC", "DEF", "GHI" };
            string camlQuery = CreateCAMLQuery(parameters);
            Console.WriteLine(camlQuery);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
        Console.WriteLine("Press any key...");
        Console.ReadKey();
    }
    
    private static string CreateCAMLQuery(string[] parameters)
    {
        StringBuilder sb = new StringBuilder();
    
        if (parameters.Length == 0)
        {
            // perhaps set a default query?
            AppendEQ(sb, "all");
        }
    
        // "AND" each parameter to the query
        for (int i = 0; i < parameters.Length; i++)
        {
            AppendEQ(sb, parameters[i]);
    
            if (i > 0)
            {
                sb.Insert(0, "<And>");
                sb.Append("</And>");
            }
        }
    
        sb.Insert(0, "<Where>");
        sb.Append("</Where>");
    
        return sb.ToString();
    }
    
    private static void AppendEQ(StringBuilder sb, string value)
    {
        // put your field's internal name in place of Category
        sb.Append("<Eq>");
        sb.Append("<FieldRef Name='Category'/>");
        sb.AppendFormat("<Value Type='Choice'>{0}</Value>", value);
        sb.Append("</Eq>");
    }
    

    【讨论】:

    • 感谢您的回复。问题是我不知道它可能是任何不。 caml 查询取决于查询字符串。它将是不同选项之间的“和”运算符,因此我无法对这些进行硬编码。因为查询字符串可以是 ABC、ABD ABC、ABE、BD ABC、ABE、DE、DF ABC、ABE 的任意组合,所以我有 15 个这样的 :-)(硬编码不是一个选项)所以我想有一些动态 caml 查询等逻辑取决于计数 add And 。如果计数为 1,则为否,如果计数为 2,则为 1,就像 thta
    • 更新了我的答案.. 你很可能已经清理了查询字符串,但我的代码会创建一个查询。
    • 这在 sharepoint 2010 中要容易得多 - stackoverflow.com/a/4484656/112194
    【解决方案2】:

    检查http://camlex.codeplex.com 项目。它的创建正是为了简化使用 C# lambda 表达式创建动态 CAML 语句。另请查看我的帖子:Build dynamic CAML queries based on query string parameters

    【讨论】:

    • 哦,非常感谢,非常感谢!这应该被赞成。
    【解决方案3】:

    我开发了 C# 代码来构建动态查询。 是这样的

     public string GenerateQuery(IList<CamlQueryElements> lstOfElement)
        {
            StringBuilder queryJoin = new StringBuilder();
            string query = @"<{0}><FieldRef Name='{1}' /><Value {2} Type='{3}'>{4}</Value></Eq>";
            if (lstOfElement.Count > 0)
            {
                int itemCount = 0;
                foreach (CamlQueryElements element in lstOfElement)
                {
                    itemCount++;
                    string date = string.Empty;
                    // Display only Date
                    if (String.Compare(element.FieldType, "DateTime", true) == 0)
                        date = "IncludeTimeValue='false'";
                    queryJoin.AppendFormat(string.Format(query, element.ComparisonOperators,
                                    element.FieldName, date, element.FieldType, element.FieldValue));
    
                    if (itemCount >= 2)
                    {
                        queryJoin.Insert(0, string.Format("<{0}>", element.LogicalJoin));
                        queryJoin.Append(string.Format("</{0}>", element.LogicalJoin));
                    }
                }
                queryJoin.Insert(0, "<Where>");
                queryJoin.Append("</Where>");
            }
            return queryJoin.ToString();
        }
    

    IList lstOfElement 是包含过滤器元素的自定义对象。您可以创建自己的对象并传递给此方法。

    【讨论】:

      【解决方案4】:

      当您有多个输入时创建 CAML 查询字符串的基本算法是:

      • 如果只检查一个值,则不需要&lt;And&gt;,只需创建代码即可
      • 如果你有两个值,你需要&lt;and&gt;(value1)(value2)&lt;/and&gt;
      • 如果你有两个以上,你创建一个循环(伪代码,对不起):

        foreach (item in values)
         sQuery = "<And>" + sQuery + item + "</And>"
        end foreach
        

      【讨论】:

      • 你能告诉我如何准确地做到这一点你的第三个选项。我想做类似的事情。就像基于计数添加 AND 一样。如果计数为 1,则否 AND,如果计数为 2,则添加一个 ADD...像这样
      • 不正确,因为 CAML 结构是 soemthingsomethingsomething
      • @Janis Veinbergs - 确切地说,这就是为什么我在当前查询字符串前面添加 "And" 并在末尾附加新语句和结束 `"" 的原因。这会生成您正在显示的相同表达式树。
      • 啊,很抱歉投反对票 :( 你可以编辑答案,这样我就可以重置我的投反对票了。
      【解决方案5】:

      如果你不喜欢使用 String Concat 方法,你可以试试 JohnHolliday's Lib - CAML.NET,我在我的项目中使用它,它只是摇滚。

      你也会喜欢的

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多