Проблема с динамическим запросом caml sharepoint?

Я хочу выполнить динамический запрос caml на основе строки запроса. Позвольте мне объяснить это на примере

мой запрос может быть любым

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

так что нет. может быть что угодно, теперь проблема начинается

Я хочу запросить свой список sharepoint на основе этой строки запроса

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

так что моя строка содержит весь запрос

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

Я хочу запросить свой список точек доступа на основе этой строки запроса и с помощью «И»

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

если есть только одна строка запроса, тогда только где _5 _.... поэтому я хочу, чтобы моя строка запроса была динамической .... Любая идея, как добиться этого ??


person AB.    schedule 31.12.2009    source источник


Ответы (5)


Предполагая, что вы говорите о поле выбора с несколькими вариантами выбора ... скорее всего, вам придется каждый раз создавать запрос.

Ваш код должен будет определить, сколько категорий передано, а затем сгенерировать CAML. Например, если передается только ABC, ваш запрос будет (обратите внимание, что тегов <And> нет):

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

Но если у вас есть три варианта, переданных через QueryString: ABC, ABD и ABE, вы получите (обратите внимание, что теги <And> окружают каждую группу из двух):

<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>");
}
person Kit Menke    schedule 31.12.2009
comment
Спасибо за отзыв. Проблема в том, что я не знаю, могло ли быть какое-то «нет». запросов caml в зависимости от строки запроса. Это будет оператор and между различными параметрами, поэтому я не могу их жестко закодировать. потому что строка запроса может быть любой комбинацией ABC, ABD ABC, ABE, BD ABC, ABE, DE, DF ABC, ABE так, как это много, у меня есть 15 таких: -) (жесткое кодирование не вариант) Итак, я думал о том, чтобы иметь некоторые логика, такая как динамический запрос caml, где в зависимости от количества добавляется и. ЕСЛИ count равен 1, то нет, а если count равен 2, то 1 и как thta - person AB.; 31.12.2009
comment
Обновил мой ответ .. вам, скорее всего, придется очистить строку запроса, но мой код создаст запрос. - person Kit Menke; 31.12.2009
comment
В sharepoint 2010 это намного проще - stackoverflow.com/a/4484656/112194 - person ScottE; 22.05.2012

проверьте проект http://camlex.codeplex.com. Он был создан как раз для упрощения создания динамических операторов CAML с использованием лямбда-выражений C #. Также проверьте мою публикацию: Создание динамических запросов CAML на основе параметры строки запроса

person alex    schedule 09.03.2011
comment
Ооо, спасибо вам большое, большое вам спасибо! Это должно быть одобрено. - person Janis Veinbergs; 14.04.2011

Я разработал код 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 - это настраиваемый объект, содержащий элементы фильтра. Вы можете создать свой собственный объект и перейти в этот метод.

person Avinash    schedule 08.03.2012

Базовый алгоритм создания строки запроса CAML при наличии нескольких входных данных:

  • Если нужно проверить только одно значение, <And> вам не нужен, просто создайте код
  • Если у вас есть два значения, вам понадобится <and>(value1)(value2)</and>
  • Если у вас их больше двух, вы создаете цикл (псевдокод, извините):

    foreach (item in values)
     sQuery = "<And>" + sQuery + item + "</And>"
    end foreach
    
person naivists    schedule 31.12.2009
comment
не могли бы вы рассказать мне, как именно это сделать, ваш 3-й вариант. Я хочу сделать что-то подобное. например, добавить И на основе количества. Если count равен 1, то нет И, а если count равен 2, добавьте один ADD ... вот так - person AB.; 31.12.2009
comment
Неправильно, потому что структура CAML - это ‹And› ‹And› ‹And› что-то ‹/And› что-то ‹/And› что-то ‹/And› - person Janis Veinbergs; 14.04.2011
comment
@Janis Veinbergs - именно поэтому я добавляю "And" перед текущей строкой запроса и добавляю новый оператор и закрывающий `‹/And› в конце. Это сгенерирует то же дерево выражений, которое вы показываете. - person naivists; 15.04.2011
comment
Ах, извините за отрицательный голос :( Вы можете отредактировать ответ, чтобы я мог сбросить свой отрицательный голос. - person Janis Veinbergs; 15.04.2011

Если вам не нравится использовать метод String Concat, попробуйте Библиотеку JohnHolliday - CAML.NET, Я использую его в своем проекте, и он просто потрясающий.

Вам тоже это понравится

person Kusek    schedule 02.01.2010