Разработка
18
Июн
10

FetchXML

FetchXML – это внутренний язык запросов к базе данных, который используется в Microsoft Dynamics CRM. Он основан на схеме, которая описывает возможности языка. Т.е. в FetchXML используется серия предопределенных команд, написанных на XML. В Microsoft Dynamics CRM данный язык применяется, например, для генерации запросов Расширенного поиска, для хранения пользовательских представлений (в объекте userquery или в объекте savedquery) и т.д.

Лучше всего представать FetchXML как некой аналог языка SQL (если конечно Вы с ним знакомы) и разобраться в этом языке именно на примере SQL. А в качестве конструкции SQL будем использовать прямые запросы к БД CRM, а точнее к таблицам хранящим объекты (в данном слчае объекта Интерес)

Пример 1

SQL:

//Выбрать все записи объекта Интерес
SELECT * FROM Leads

FetchXML:

<fetch mapping='logical'>
	<entity name='lead'>
		<all-attributes/>
	</entity>
</fetch>

Разбор полетов:

Корневой элемент любого Fetch запроса — fetch:

<fetch mapping='logical'>
</fetch>

Я точно не знаю для чего служит атрибут mappings, но он может иметь три значения logical, internal и physical. И по умолчанию имеет тип logical (поэтому его и ставьте).

Затем идет элемент entity, который содержит в параметре name название объекта, записи которого Вы хотите возвратить.

<entity name=''>
</entity>

Далее идет элемент, в котором мы указываем, какие поля необходимо вернуть. В этом случае мы возвращаем все поля объекта.

<all-attributes/>

Пример 2

SQL:

//Выбрать первые 10 записей из объекта Интерес
SELECT TOP 10 * FROM Leads

FetchXML:

<fetch mapping='logical' count='10'>
	<entity name='lead'>
		<all-attributes/>
	</entity>
</fetch>

Разбор полетов:

Единственным новым атрибутом здесь является count. Который указывает какое количество записей вернуть (т.е. если их будет больше, то они будут «усечены»).

В этом контексте стоит рассмотреть еще один атрибут — Page:

<fetch mapping='logical' count='10' page='2'>
	<entity name='lead'>
		<all-attributes/>
	</entity>
</fetch>

Page не имеет никакого эквивалента в языке SQL. В FetchXM этот атрибут используется для того, чтобы оперделить какой набор записей вернуть. Если не использовать page, то будут возвращены всегда первые строки. А если нам нужны строки с 20 по 30? Вот тут то и пригодится этот page. Т.е. система грубо говоря разобъет все отобранные записи на наборы, в каждом их которые будет число записей равное count (конечно же для последнего набора записей может не хватить и он будет меньше) и вернет тот набор записей который указан в page.

Пример 3

SQL:

//Возвращаем определенные поля объекта Интерес
SELECT FirstName, LastName FROM Leads

FetchXML:

<fetch mapping='logical'>
	<entity name='lead'>
		<attribute name='firstname' />
		<attribute name='lastname' />
	</entity>
</fetch>

Разбор полетов:

Тут все довольно просто. Если Вам нужны не все поля объекта, а только некоторые, необходимо вместо <all-attributes/> использовать <attribute>. Причем сколько полей Вы хотите вернуть, столько и элементов <attribute> должны использовать в запрсе. А в параметре name необходимо указать имя поля, заначение которого желаете вернуть.

Пример 4

SQL:

//Вернуть записи объекта Интерес, в которых название компании равно «Microsoft»
SELECT * FROM Leads WHERE CompanyName = 'Microsoft'

FetchXML:

<fetch mapping='logical'>
	<entity name='lead'><all-attributes/>
		<filter type='and'>
			<condition attribute='companyname' operator='eq' value='Microsoft' />
		</filter>
	</entity>
</fetch
&#91;/xml&#93;

<strong>Разбор полетов:</strong>

Пора приступить к фильтарции данных… Итак, на этот раз нам нужны не все записи, атолько часть (в данном случаи, те где название компании = Microsoft). В FetchXML фильтрация происходит с помощью следующей конструкции:


<filter type='and'>
</filter>

Элементе filter всегда «обрамляет» условия запроса, а параметр Type определяет логическое поведение при наличии нескольких условий. В данном примере условие одно, но если бы их было два или больше, то значение параметра Type определяло бы, необходимо ли соответствие всем условиям (значение and) или достаточно одного или нескольких совпадений по условиям (значение or).

Затем идет элемент condition, где мы задаем само условие:

<condition attribute='companyname' operator='eq' value='Microsoft' />

Элемент Condition состоит из 3 основных частей: Attribute, Operator и Value. В данном случаи это аналог CompanyName = ‘Microsoft’ из SQL запроса:

  • Параметр fieldname содержит имя поля по которому происходит фильтрация.
  • Operator это логическое условие (больше, меньше, равно и т.д.). Значение параметра Operator в этом прмиере – «eq», который является сокращением от слова «equals » (что переводится как «равный»). Полный набор возможных логических условий смотрите на msdn.
  • Ну и наконец, параметр value, который содержит искомое значение поля.

Пример 5

SQL:

//Выбрать записи объекта Интерес, в которые имя начинается на «В» и фамилия равна Петров
SELECT * FROM Leads WHERE FirstName LIKE ‘В%’ AND LastName = ‘Петров’

FetchXML:

<fetch mapping='logical'>
	<entity name='lead'>
    	<all-attributes/>
		<filter type='and'>
			<condition attribute='firstname' operator='like' value='В%'/>
			<condition attribute='lastname' operator='eq' value='Петров'/>
		</filter>
	</entity>
</fetch>

Разбор полетов:

Этот пример похож на пердыдущий, за исключением двух моментов: здесь два условия и используется новый логические опреатор like (работает точно так же как like в SQL). В элементе filter параметр type задан как and, т.е. чтобы запись попала в выборку должны быть соблюдены оба условия в обязательном порядке.Условие же like в данном примере трактуется так: первый символ поля имя должен быть «В», а все остальные какие угодно. Т.е. комбинированием букв, цифр и служебных символов (в данном случаи им является %) мы задаем своего рода маску!

Пример 6

SQL:

//Выбрать записи объекта интерес, где, либо имя начинается на «В» и фамилия равна Петров, либо название компании равно «Microsoft»
SELECT * FROM Leads WHERE (FirstName LIKE ‘J%’ AND LastName = ‘Smith’) OR CompanyName = ‘Microsoft’

FetchXML:

<fetch mapping='logical'>
	<entity name='lead'>
    	<all-attributes/>
		<filter type='or'>
			<filter type='and'>
				<condition attribute='firstname' operator='like' value='J%' />
				<condition attribute='lastname' operator='eq' value='Smith' />
			</filter>
			<condition attribute='companyname' operator='eq' value='Microsoft' />
		</filter>
	</entity>
</fetch>

Разбор полетов:

Еще немного усложним предыдущий пример, добавив группировку условий. Посмотрим на условие в SQL:

(FirstName LIKE ‘J%’ AND LastName = ‘Smith’) OR CompanyName = ‘Microsoft’

Мы видем здесь группировку верхнего уровня OR и локальную грппировку в скобках AND. Чтобы реализовать такое в FetchXML нужно просто в место скобок использовать внутренний элемент filter. Для первого элемента filter мы используем логическое условие OR (т.е условие верхнего уровня в SQL), а для внутреннего filter условие AND (также как и для условия в скобках в SQL). Таким образом для условий внутреннего элемента filter используется логические условие OR. А между внутренним элементом filter и условием верхнего уровня используется логическое условие AND.

Эпилог

Есть еще много дргих параметров FetchXML, в часности объединение с другими объектами для поиска условий по связанным записям, но это уже совсем другая история (о которой расскажу немного позже) 🙂 Также, с этими и другими примерами FetchXML Вы можете ознакомится самостоятельно на MSDN.

А том, как на практике применять FetchXML и делать с его помощью интересные фишки, читайте в следующих постах 🙂

Комментарии (10)
  • Борис 18.06.2009

    Добрый день!
    Спасибо за шикарные обучающие посты!!!
    Подскажите новичку в составлении FETCH запросов — возможно ли в условии выбора произвести вычисление с которым сравнивать поле, то есть например, что-то такое

    то есть вернуть записи, в которых значение поля field в полтора раза больше сравнимого поля field?
    и если нельзя, то какие возможны варианты обойти или как сделать?

  • Борис 18.06.2009

    Кажется сайт все съел
    смысл вот
    condition attribute=»field» operator=»ge» value=1.5*»{entity.field}»

  • slivka_83 18.06.2009

    Добрый день.
    Фетч это XML почти точное отражение Расширенного поиска. Вот все что в нем Вы сможете сделать, то сможете составить с помощью фетча. К сожалению производить математически операции или сравнивать с другими полями Расширенный поиск не может.

  • Борис 18.06.2009

    Ну сравнивать с другими полями я его немножко научил, но вот математические операции он у меня действительно не ест(
    Спасибо!

  • Николай 18.06.2009

    Здравствуйте!
    Благодарю за шикарные советы!
    Для коннекта сайта на php с dynamics 2011 использую php-dynamics-crm-2011-1.0.3, которая позволяет использовать к CRM запросы FetchXML. Насколько я понимаю, с помощью FetchXML, я могу только получать данные (запросы типа SELECT), подскажите, чем удалять и изменять записи? В какую сторону копать?

  • slivka_83 18.06.2009

    Добрый день.

    Нужно копать в сторону SOAP-запросов (http://msdn.microsoft.com/en-us/library/gg594434.aspx). Вот что нашел на скорую руку: https://github.com/Ben-Speakman/PHP-Dynamics-Online-CRM-2011-SOAP-Class

  • joman 18.06.2009

    Возможно ли в fetchXML сделать что то вроде:
    select FullName, BirthDate from filteredContact
    where MONTH(BirthDate) = 3
    order by FullName

  • joman 18.06.2009

    А такой запрос:
    select FullName, BirthDate from filteredContact
    where MONTH(BirthDate) = 3
    order by FullName
    в FetchXML можно перевести?

  • joman 18.06.2009

    Возможно ли с Fetch выбрать что то вроде такого:
    select Fullname from contact
    where month(BirthDate) = 3

  • slivka_83 18.06.2009

    Насколько я знаю — нет.

*

code