AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 19.08.2013, 19:00   #1  
IKA is offline
IKA
Участник
 
359 / 65 (3) ++++
Регистрация: 15.03.2006
new Query(q1); и Query(q1.pack()); - есть ли разница ?
Есть запрос q1.

Есть ли разница, каким образом создавать его копию:
через q2 = new Query(q1.pack()); или через q3 = new Query(q1); ?

AX2009, RU2
Старый 19.08.2013, 21:16   #2  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Из известных мне особенностей упаковки Query: теряются dynalink'и (для этого надо явно отключить проверку через параметр _doCheck, иначе Query с dynalink'ами не упакуется и выкинет исключение) и теряются хинты forceNestedLoop, forceSelectOrder. Иногда потеря этих хинтов ведет к серьезным проблемам с производительностью, впрочем, их и не используют "просто так". А еще важно, на каком уровне (клиенте или сервере) создан исходный Query и на каком будет использоваться результирующий: при передаче с уровня на уровень лучше сделать копию исходного Query, используя переупаковку.
За это сообщение автора поблагодарили: mazzy (10), MikeR (15), IKA (1), dech (2).
Старый 20.08.2013, 12:29   #3  
IKA is offline
IKA
Участник
 
359 / 65 (3) ++++
Регистрация: 15.03.2006
здорово, спасибо!
Старый 20.08.2013, 16:10   #4  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Собственно, вот пара вспомогательных методов для класса SysQuery. С помощью первого можно безопасно копировать запросы, в т.ч. при передаче с клиента на сервер и обратно.
X++:
/// <summary>
/// копируем запрос, по ходу перебивая dynalink'и в locked ranges
/// </summary>
/// <param name="_q">
/// исходный запрос
/// </param>
/// <param name="_copyHints">
/// надо ли копировать хинты forceSelectOrder и forceNestedLoops
/// </param>
/// <returns>
/// копия исходного запроса
/// </returns>
/// <remarks>
/// может быть полезно, если запрос затем будет сохраняться в SysLastValue, либо передавать между клиентом и сервером, либо рихтовать под ные нужды (подсчет записей)
/// </remarks>
/// <exception cref="Exception::Error">
/// выбрасывается, если исходный запрос - "вырожденный" либо вовсе null
/// </exception>
public client server static Query copyQuery(
    Query   _q,
    boolean _copyHints = true
    )
{
    QueryBuildDataSource    qbdsOld;
    QueryBuildDataSource    qbdsNew;
    QueryBuildDynalink      qbdl;
    Query                   ret;
    str                     sq;
    Counter                 n;
    ;
    if (!(_q && _q.dataSourceCount() > 0))
    {
        throw error(Error::wrongUseOfFunction(funcname()));
    }
    ret = new Query(_q.pack(false));            // создать копию запроса
    if (_copyHints)
    {
        // на эти извращения пришлось пойти потому, что у методов Query forceSelectOrder() и forceNestedLoop() параметры обязательны,
        // поэтому их нельзя использовать как нормальные свойства для определения наличия или отсутствия соотв. хинтов в запросе
        sq = _q.dataSourceNo(1).toString();
        if (match(@"^SELECT WITH.* SELECT_ORDER[ ,]", sq))
        {
            ret.forceSelectOrder(true);
        }
        if (match(@"^SELECT WITH.* NESTED_LOOP[ ,]", sq))
        {
            ret.forceNestedLoop(true);
        }
    }
    qbdsNew = ret.dataSourceNo(1);              // из нового запроса
    qbdsOld = _q.dataSourceNo(1);               // из исходного запроса
    for (n = 1; n <= qbdsOld.dynalinkCount(); n++)
    {
        qbdl = qbdsOld.dynalink(n);
        // очищаем *все* range'и по данному полю и ставим свой range с нужным статусом
        SysQuery::setFieldRange(qbdsNew, qbdl.field(), queryValue(qbdl.cursor().(qbdl.dynamicField())), RangeStatus::Locked);
    }
    return ret;
}
/// <summary>
/// устанавливает фильтр по полю, удаляя все прочие и опционально управляя его статусом
/// </summary>
public static QueryBuildRange setFieldRange(
    QueryBuildDataSource    _qbds,
    fieldId                 _fieldId,
    Range                   _rangeValue,
    RangeStatus             _rangeStatus = RangeStatus::Open
    )
{
    QueryBuildRange ret;
    ;
    if (_qbds)
    {
        while (_qbds.findRange(_fieldId))
        {
            _qbds.clearRange(_fieldId);
        }
        ret = _qbds.addRange(_fieldId);
        ret.value(_rangeValue);
        ret.status(_rangeStatus);
    }
    return ret;
}
За это сообщение автора поблагодарили: raz (10), virtuoso (1).
Теги
query, законченный пример, как правильно

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
fatihdemirci: CrossCopmany ile query yazmak Blog bot DAX Blogs 0 17.08.2010 16:05
Dynamics AX Geek: Using query() Blog bot DAX Blogs 0 04.05.2009 14:05
Dynamics AX: QueryRun and Query Objects - Binding operation failed to allocate buffer space Blog bot DAX Blogs 0 03.04.2009 08:05
Проблема с составлением Query axaLearner DAX: Программирование 10 01.12.2005 15:00
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 13:32.