Кастомизация
16
Мар
5

Быстрый поиск 2.0

Быстрый поиск по умолчанию производит поиск среди записей объекта, для который отображается текущее Представление. При этом используется фильтрация такого вида: «А%», т.е. ищет с начала строки. Вы конечно можете ручками изменить такое поведение, задав маску «*А*». Но иногда требуется чтобы поиск по вхождению строки производился по умолчанию.

Создайте такой плагин:

using System;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Messages;
using System.Globalization;

namespace quickSearch
{
    public class quickSearch : IPlugin
    {
        // Исковамая строка - "Query" и спецсимвол, который будет использоваться в операторе LIKE
        public const String QueryLiteral = "Query";
        public const String LIKE = "%";
        
        public void Execute(IServiceProvider serviceProvider)
        {
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            String ParentEntity, OriginalSearch = String.Empty;

            try
            {
                IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

                // Проверяем, что InputParameters содержат "Query"
                if (context.Depth < 2 && context.InputParameters.Contains(QueryLiteral) && context.InputParameters[QueryLiteral] is QueryExpression)
                {
                    QueryExpression QueryPointer = (context.InputParameters[QueryLiteral] as QueryExpression);
                    // Проверьте, что преобразование прошло успешно - в противном случае остальные действия бесполезны
                    if (null != QueryPointer)
                    {
                        // Проверяем, что запрос пришел из Представления посика: критерии не должен быть пустыми и число фильтров должно быть > 1
                        if (null != QueryPointer.Criteria && QueryPointer.Criteria.Filters.Count > 1)
                        {
                            // Берем отправленный запрос и добавляем к нему в начале "%"
                            ParentEntity = context.PrimaryEntityName;
                            OriginalSearch = QueryPointer.Criteria.Filters[1].Conditions[0].Values[0].ToString();
                            OriginalSearch = String.Format(CultureInfo.CurrentCulture, "{0}{1}", LIKE, OriginalSearch);
                        }

                        if (null != QueryPointer.Criteria)
                        {
                            // Изменитесь дефолтный оператор "А%" на полный Like (т.е. "%А%") в критерии посика
                            foreach (FilterExpression FilterSet in QueryPointer.Criteria.Filters)
                            {
                                foreach (ConditionExpression ConditionSet in FilterSet.Conditions)
                                {
                                    if (ConditionSet.Operator == ConditionOperator.Like)
                                    {
                                        ConditionSet.Values[0] = OriginalSearch;
                                    }
                                }
                            }
                        }
                    }
                    context.InputParameters[QueryLiteral] = QueryPointer;
                }
            }
            catch (FaultException<OrganizationServiceFault> ex)
            {
                throw new InvalidPluginExecutionException("An error occurred in the plug-in.", ex);
            }
        }
    }
}

Сначала мы получаем ссылку на InputParameter и а из них уже ссылку на QueryExpression. Из нее вытаскиваем отправленный запрос и добавляем перед ним символ процента (%). Что в операторе Like означает любое количество, любых символов. После этого запрос будет выглядеть примерно так: «%А%». Далее помещаем изменённый запрос в QueryExpression, тем самым подменяя запрос.

Соберите плагин и зарегистрируйте его на Pre RetrieveMultiple нужного объекта.

Данный механизм можно модифицировать, чтобы производить поиск среди связанных записей, или любые другие условия – все то, что поддерживает QueryExpression.


Комментарии (5)
  • Игорь 16.03.2013

    Подскажите пожалуйста, какие библиотеки из 2011 SDK подключать нужно ? 🙁
    У меня ругается на using System.ServiceModel;
    и на (FaultException ex)

  • slivka_83 16.03.2013

    На этом сайте есть статьи описывающие процесс с основ. начните изучение плагинов с них.

  • Игорь 16.03.2013

    Да уже нашел — это две статьи — основы написания плагинов и 10 отличий…
    Но возникла другая проблема 🙁
    Есть ли способ регистрировать плагин не через Registration tool? Дело в том что у меня на сервере поднят ADFS и IDF и утилита не видит базы CRM-овские :(((
    Может есть способ прописать в ручную?

  • Павел 16.03.2013

    Подскажите, данный способ подойдет для CRM 4.0? И как его можно «модифицировать, чтобы производить поиск среди связанных записей»?
    Спасибо!

  • slivka_83 16.03.2013

    «Концепция» должна подойти, а вот код нужно переписать в соответствии с CRM SDK 4.0.

*

code