Записи с меткой «Софт»

PostHeaderIcon Ошибка “Не удалось завершить эту операцию. Повторите попытку. 0×80004005″ в SharePoint и правила построения запросов с “Or”

Запрос для выбора записей (задач), назначенных на некоторый круг пользователей и не являющихся завершенными:

<Query>
    <Where>
        <And>
            <Or>
                <Includes>
                    <FieldRef Name='AssignedTo' />
                    <Value Type='Lookup'>user01</Value>
                </Includes>
                <Includes>
                    <FieldRef Name='AssignedTo' />
                    <Value Type='Lookup'>user02</Value>
                </Includes>
                <Includes>
                    <FieldRef Name='AssignedTo' />
                    <Value Type='Lookup'>user03</Value>
                </Includes>
            </Or>
            <Neq>
                <FieldRef Name='_x0421__x043e__x0441__x0442__x04' />
                <Value Type='Text'>Завершена</Value>
            </Neq>
        </And>
    </Where>
</Query>

Данный запрос возвратит ошибку “Не удалось завершить эту операцию. Повторите попытку. 0×80004005“.

Запрос выглядит довольно правдоподобным и так сразу и не скажешь в чем причина ошибки. Однако, причина довольно банальна – запрос не верен, так как оператор Or может принимать только два условия для сравнения (а в запросе их три). Кому из разработчиков CAML пришла в голову идея сделать именно так (ведь это откровенный бред!) не известно, но факт остается фактом – корректный запрос в данному случае должен выглядеть так:

<Query>
    <Where>
        <And>
            <Or>
                <Includes>
                    <FieldRef Name='AssignedTo' />
                    <Value Type='Lookup'>user01</Value>
                </Includes>
                <Or>
                    <Includes>
                        <FieldRef Name='AssignedTo' />
                        <Value Type='Lookup'>user02</Value>
                    </Includes>
                    <Includes>
                        <FieldRef Name='AssignedTo' />
                        <Value Type='Lookup'>user03</Value>
                    </Includes>
                </Or>
            </Or>
            <Neq>
                <FieldRef Name='_x0421__x043e__x0441__x0442__x04' />
                <Value Type='Text'>Завершена</Value>
            </Neq>
        </And>
    </Where>
</Query>

Дабы избежать подобных ошибок и упростить себе работу по построению запросов на просторах интернета найден программа U2U CAML Query Builder for SharePoint 2003 and SharePoint 2007 (Windows Version).

Для программного создания подобных условий пришлось написать такой вот метод:

// [C#]
private static string CreateOrLookupConditions(string comparisonOperator, string fieldName, string[] wssValues)
{
    if (wssValues == null || wssValues.Length < 1)
        return string.Empty;
    var tpl = "<" + comparisonOperator + "><FieldRef Name='" + fieldName + "' /><Value Type='Lookup'>{0}</Value></" + comparisonOperator + ">";
    var conditionString = string.Format(tpl, wssValues[0]);
    if (wssValues.Length == 1)
        return conditionString;
    for (var i = 1; i < wssValues.Length; i++)
        conditionString = "<Or>" + conditionString + string.Format(tpl, wssValues[i]) + "</Or>";
    return conditionString;
}

// Использование
var users = new string[] { "user01", "user02", "user03" };
var conditions = CreateOrLookupConditions("Includes", "AssignedTo", users);