Вопрос

Добрый день!

Подскажите, как средствами серверной ESQ реализовать такой запрос

select o.Number
from [Order] o
where not exists(
	select null
	from OrderProduct op
	where op.OrderId = o.Id
	and op.TypeId = '29468170-1C73-4851-967B-90E5C108AEF9' --some type
)

Не получается задать связь op.OrderId = o.Id в подзапросе.

У меня такой же вопрос

6 комментариев
Лучший ответ

Максим.Паламарчук,
Попробуйте такой вариант

var esq = new EntitySchemaQuery(_userConnection.EntitySchemaManager, "Order");
            esq.AddAllSchemaColumns();
var filtersByExisting = new EntitySchemaQueryFilterCollection(esq);
		filtersByExisting.IsNot = true;
		var notExFilter = esq.CreateFilterWithParameters(
			FilterComparisonType.IsNotNull,
			"[OrderProduct:Order].Id");
		filtersByExisting.Add(notExFilter);
		filtersByExisting.Add(esq.CreateFilterWithParameters(FilterComparisonType.Equal,
			"[OrderProduct:Order].Type.Id", new Guid("29468170-1C73-4851-967B-90E5C108AEF9")));
			esq.Filters.Add(filtersByExisting);
           var entityCollection = esq.GetEntityCollection(_userConnection);

 

Через Select:

var select = new Select(_userConnection)
            .Column("o", "Number")
            .From("Order").As("o")
            .Where()
                .Not().Exists(
                    new Select(_userConnection).Column("op", "Id").From("OrderProduct").As("op").Where("op", "OrderId ").IsEqual("o", "Id")
                    .And("op", "TypeId").IsEqual(Column.Parameter("29468170-1C73-4851-967B-90E5C108AEF9"))
                );

Через ESQ:

var esq = new EntitySchemaQuery(_userConnection.EntitySchemaManager, "Order");
            esq.AddAllSchemaColumns();
            esq.Filters.Add(esq.CreateFilterWithParameters(FilterComparisonType.Equal, "Type", new Guid("29468170-1C73-4851-967B-90E5C108AEF9")));
            esq.Filters.Add(esq.CreateFilterWithParameters(FilterComparisonType.NotExists, "[OrderProduct:Order:Id].Id"));
            var entityCollection = esq.GetEntityCollection(_userConnection);

 

Сидоров Александр В.,

насчет Select я согласен, а вот в esq, мне кажется, что колонка Type относится к схеме Order, а не OrderProduct, или я не прав?

Максим.Паламарчук, 
Да, согласен. Нужно Type внести во внутренний запрос

Сидоров Александр В.,

А каким образом это реализовать?

Максим.Паламарчук,
Попробуйте такой вариант

var esq = new EntitySchemaQuery(_userConnection.EntitySchemaManager, "Order");
            esq.AddAllSchemaColumns();
var filtersByExisting = new EntitySchemaQueryFilterCollection(esq);
		filtersByExisting.IsNot = true;
		var notExFilter = esq.CreateFilterWithParameters(
			FilterComparisonType.IsNotNull,
			"[OrderProduct:Order].Id");
		filtersByExisting.Add(notExFilter);
		filtersByExisting.Add(esq.CreateFilterWithParameters(FilterComparisonType.Equal,
			"[OrderProduct:Order].Type.Id", new Guid("29468170-1C73-4851-967B-90E5C108AEF9")));
			esq.Filters.Add(filtersByExisting);
           var entityCollection = esq.GetEntityCollection(_userConnection);

 

Сидоров Александр В.,

спасибо, все работает. Свойство IsNot как раз то, что нужно

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Добрый день коллеги.
Столкнулся со странной ситуацией. Обратился к ТС, но все же решил и тут задать свой вопрос:
При реализации очередной кастомизации необходимо было выполнить запрос EntitySchemaQuery:
    
    var esq = new EntitySchemaQuery(UserConnection.EntitySchemaManager.GetInstanceByName("ServiceEngineer"));
    var colId = esq.AddColumn(esq.CreateAggregationFunction(AggregationTypeStrict.Count, "Id"));
    var esqFilter = esq.CreateFilterWithParameters(FilterComparisonType.Equal, "ServiceItem", serviseId);
    esq.Filters.Add(esqFilter);
    result = esq.GetSelectQuery(UserConnection).GetSqlText();
    return result;

Реализовывал с использованием ServiceHelper, где для анализа данных реализовал два метода: GET и POST.
Странность заключается в том, что исходный код у данных методов одинаков, а результат разный (см. аттач GET.png и POST.png)

У меня такой же вопрос

1 комментарий

Вероятно, дело не в GET и POST, а в том, что второй раз запускается под пользователем, у которого нет прав на таблицу ServiceEngineer. См. тут или тут.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Добрый день.

Стоит задача из таблицы детали достать все записи по полю UsrSchoolName1Id равные Id раздела(this.get("Id")).

И посчитать количество записей по UsrPositionStaffId равной 07D2E5FA-1B0F-4B54-90AB-CCE23678ECFD.

Мой код:

isAccountPrimaryContactSet: function() {
var message = "";
var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
    rootSchemaName: "UsrEntity1DetailStaff"
});
esq.addColumn("Id");
esq.addColumn("UsrPositionStaffId");
esq.addColumn("UsrSchoolName1Id");
var esqFirstFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,"UsrSchoolName1Id", this.get("Id"));
var esqSecondFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,"UsrPositionStaffId", "07e2e5fa-1b0f-4b54-90ab-cce23678ecfd");
esq.filters.logicalOperation = Terrasoft.LogicalOperatorType.AND;
esq.filters.add("esqFirstFilter", esqFirstFilter);
esq.filters.add("esqSecondFilter", esqSecondFilter);
esq.addAggregationSchemaColumn("UsrPositionStaffId", Terrasoft.AggregationType.COUNT, Terrasoft.AggregationEvalType.ALL);
esq.getEntityCollection(function (result) {
    if (!result.success) {
        this.showInformationDialog("Ошибка запроса данных");
        return;
    }
    result.collection.each(function (item) {
        message += "Количество младших сотрудников: " + item.get("UsrPositionStaffId") + "\n";
    });
    this.showInformationDialog(message);
}, this);
 
 
 
}

Фото моей таблицы:

 

 

 

 

После нажатия кнопки данный код выводит следующую ошибку в консоли:

 

У меня такой же вопрос

10 комментариев
Лучший ответ

Все id для js приводите к нижнему регистру те использовать вместо 

"77250D61-1612-4D2B-BE38-361AF1E27E59"

нужно

"77250d61-1612-4d2b-be38-361af1e27e59"

Для решение вашей проблемы посмотрите через профайлер sql запросов какой запрос идет в базу это поможет вам понять что не так с запросом и почему он не возвращает записей

Насколько я понимаю, то в колонках "UsrPositionStaffId" и "UsrSchoolName1Id" Вам нужно убрать в конце "Id".

Alex Zaslavsky пишет:

Насколько я понимаю, то в колонках "UsrPositionStaffId" и "UsrSchoolName1Id" Вам нужно убрать в конце "Id".

 

Ошибка ушла теперь просто возвращает пустое поле. 

Казанцев Андрей Юрьевич,

я, честно говоря, ниразу не использовал AggregationSchemaColumn, я обычно пишу:

if (!result.success) {
  this.showInformationDialog("Ошибка запроса данных");
    return;
  }
this.showInformationDialog(result.collection.collection.length);

Это так, чисто протестить сколько записей я получил.

Alex Zaslavsky пишет:

Казанцев Андрей Юрьевич,

я, честно говоря, ниразу не использовал AggregationSchemaColumn, я обычно пишу:


 
if (!result.success) {
  this.showInformationDialog("Ошибка запроса данных");
    return;
  }
this.showInformationDialog(result.collection.collection.length);

Это так, чисто протестить что я получил.

Тут пока проблема не в агрегации, а фильтрации. Для отладки закоментировал  часть кода:

var message = "";
var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
    rootSchemaName: "UsrEntity1DetailStaff"
});
esq.addColumn("UsrPositionStaff");
esq.addColumn("UsrSchoolName1");
var esqFirstFilter = esq.createColumnFilterWithParameter("UsrSchoolName1",Terrasoft.ComparisonType.EQUAL,"UsrSchoolName1", "77250D61-1612-4D2B-BE38-361AF1E27E59");
esq.filters.logicalOperation = Terrasoft.LogicalOperatorType.AND;
esq.filters.add("esqFirstFilter", esqFirstFilter);
esq.getEntityCollection(function (result) {
    if (!result.success) {
        this.showInformationDialog("Ошибка запроса данных");
        return;
    }
    result.collection.each(function (item) {
        message += "Количество младших сотрудников: " + item.get("UsrSchoolName1") + "\n";
    });
    this.showInformationDialog(message);
}, this);

Все id для js приводите к нижнему регистру те использовать вместо 

"77250D61-1612-4D2B-BE38-361AF1E27E59"

нужно

"77250d61-1612-4d2b-be38-361af1e27e59"

Для решение вашей проблемы посмотрите через профайлер sql запросов какой запрос идет в базу это поможет вам понять что не так с запросом и почему он не возвращает записей

Метод createColumnFilterWithParameter содержит 3 параметра, а у Вас 4:

createColumnFilterWithParameter(comparisonType, columnPath, paramValue)

Попробуйте написать вот так:

esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,"UsrSchoolName1", "77250d61-1612-4d2b-be38-361af1e27e59")

Казанцев Андрей Юрьевич,

так что в итоге, все получилось?

Григорий Чех пишет:

Большое спасибо за подсказку с профайлером. Айди через get сделал.

Alex Zaslavsky пишет:

Спасибо и тебе Алекс. А то я с постоянным использованием  sql запросах в поддержке. Везде пихал за место объектов название запросов в базе.

Алла Савельева пишет:

Да, Алла ваш способ заработал. Хотя я все делал по примерам с академии.

У меня теперь такая проблема. Я не могу синхронно вывести подсчет.

Сам код подгружается так:

 onEntityInitialized: function() {
            	this.callParent(arguments);
            	  this.methodChain();
            },
	numberOfDetail: function(IdDetail) {
var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
    rootSchemaName: "UsrEntity1DetailStaff"
});
esq.addColumn("UsrPositionStaff","UsrPositionStaff");
esq.addColumn("UsrSchoolName1","UsrSchoolName1");
var esqFirstFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
"UsrSchoolName1", this.get("Id"));
var esqSecondFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,"UsrPositionStaff", IdDetail);
esq.filters.logicalOperation = Terrasoft.LogicalOperatorType.AND;
esq.filters.add("esqFirstFilter", esqFirstFilter);
esq.filters.add("esqSecondFilter", esqSecondFilter);
esq.addAggregationSchemaColumn("UsrPositionStaff", Terrasoft.AggregationType.COUNT,"detailOfNumber",
Terrasoft.AggregationEvalType.NONE);
esq.getEntityCollection(function (result) {
    if (!result.success) {
        this.showInformationDialog("Ошибка запроса данных");
        return;
    }
    result.collection.each(function (item) {
 
        return item.get("detailOfNumber");
    });
}, this);
},
methodChain: function(){
 this.showInformationDialog("Младших учителей:" + this.numberOfDetail("07D2E5FA-1B0F-4B54-90AB-CCE23678ECFD") + "\n"+
"Старших учителей:" + this.numberOfDetail("019EF537-F8F1-4C01-BA2B-4B17D1285231") + "\n" +
"Ведущих учителей:" + this.numberOfDetail("F02850E9-264A-4D57-B64C-7409F0A84322") + "\n");
 
 
}

 

return в асинхронном обработчике плохая идея вам нужно вызывать methodChain втом же месте где вы получили(вычитали данные) те после 

(result.success)

для каждого элемента коллекции или после их перебора /(это смотря что вам нужно). Как вариант можно создать свои виртуальные колонки (атрибуты) вычитать туда нужные вам данные а потом в обработчике (например по нажатию кнопки) брать оттуда данные.

Григорий Чех пишет:
return в асинхронном обработчике плохая идея вам нужно вызывать methodChain втом же месте где вы получили(вычитали данные) те после 

Задача в том чтобы при открытии страницы выходило это окно. 

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Коллеги, подскажите есть ли в EntitySchemaQuery аналог Select COUNT (*)

У меня такой же вопрос

3 комментария
Лучший ответ

Добрый день!

Подозреваю, что речь идет о сервере, но желательно это указывать в вопросе. Именно Ваш вариант можно получить примерно таким образом

new Select(UserConnection).Column(Func.Count(Column.Asterisk())).From("Account")

Если необходимо именно esq, то примерно так

var esq = new EntitySchemaQuery(UserConnection.EntitySchemaManager.GetInstanceByName("Account"));
esq.AddColumn(esq.CreateAggregationFunction(AggregationTypeStrict.Count, "Id"));

Во втором варианте будет конечно не select count(*), а select count(Id), но, думаю, нужный эффект будет достигнут.

 

Ну и на всякий случай клиент

var esq = Ext.create('Terrasoft.EntitySchemaQuery', {
	rootSchemaName: "Account"
});
esq.addAggregationSchemaColumn("Id", Terrasoft.AggregationType.COUNT, 'CountRows');

 

Добрый день!

Подозреваю, что речь идет о сервере, но желательно это указывать в вопросе. Именно Ваш вариант можно получить примерно таким образом

new Select(UserConnection).Column(Func.Count(Column.Asterisk())).From("Account")

Если необходимо именно esq, то примерно так

var esq = new EntitySchemaQuery(UserConnection.EntitySchemaManager.GetInstanceByName("Account"));
esq.AddColumn(esq.CreateAggregationFunction(AggregationTypeStrict.Count, "Id"));

Во втором варианте будет конечно не select count(*), а select count(Id), но, думаю, нужный эффект будет достигнут.

 

Ну и на всякий случай клиент

var esq = Ext.create('Terrasoft.EntitySchemaQuery', {
	rootSchemaName: "Account"
});
esq.addAggregationSchemaColumn("Id", Terrasoft.AggregationType.COUNT, 'CountRows');

 

Лопатин Константин Николаевич,

Уточню:

Речь идет о запросе на сервере.

Сам запрос выглядит так:

Select COUNT (*) as CountServiceEngineers 
FROM [dbo].[ServiceEngineer] as [ServiceEngineer]
LEFT OUTER JOIN [dbo].[ServiceItem] as [ServiceItem] on [ServiceItem].id = [ServiceEngineer].[ServiceItemId]
Where [ServiceItem].Id = '9ac3a38b-fd9f-4802-b9d7-a3bcb28f8e96'

Во втором примере выше приведен именно серверный ESQ, о котором спрашиваете. Останется только наложить фильтр, как обычно.

Кстати, в приведенном запросе даже JOIN не нужен, поскольку ServiceItemId есть прямо в ServiceEngineer.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Если не использую фильтр, то все работает, но без фильтрации
Если использую, то null на выходе

В чем может быть причина?

var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
        rootSchemaName: "GeneralForm"
    });
    
    esq.addColumn("Id");
    esq.addColumn("UsrCode");
    esq.addColumn("UsrInfoId.Name");
    esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(
    Terrasoft.ComparisonType.EQUAL, "UsrInfoId.Name", "Инфо"));
    
    var rowsCount = 0;
    var rowsCount1 = "";
    esq.getEntityCollection(function(result) {
        if (result.success) {
            
            
            result.collection.each(function (item) {
                rowsCount = rowsCount + 1;
                rowsCount1 += item.get("UsrCode") + "#" + item.get("UsrInfoId.Name") + 
                    "(" + rowsCount + ")" + "\n";
            });
            this.set("UsrCount", rowsCount1);
        }
    }, this);

У меня такой же вопрос

12 комментариев
Лучший ответ

Посмотрите профилировщиком какой sql запрос отправляется в БД, это поможет определить проблему

Посмотрите профилировщиком какой sql запрос отправляется в БД, это поможет определить проблему

Ошибка в том, что Вы неправильно построили связи - нужно писать UsrInfo.Name, а у Вас UsrInfoId.Name.

Вот корректный код:

var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
        rootSchemaName: "GeneralForm"
    });
    
    esq.addColumn("Id");
    esq.addColumn("UsrCode");
    esq.addColumn("UsrInfo.Name");
    esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(
    Terrasoft.ComparisonType.EQUAL, "UsrInfo.Name", "Инфо"));
    
    var rowsCount = 0;
    var rowsCount1 = "";
    esq.getEntityCollection(function(result) {
        if (result.success) {
            
            
            result.collection.each(function (item) {
                rowsCount = rowsCount + 1;
                rowsCount1 += item.get("UsrCode") + "#" + item.get("UsrInfo.Name") + 
                    "(" + rowsCount + ")" + "\n";
            });
            this.set("UsrCount", rowsCount1);
        }
    }, this);

Ну, и на будущее смотрите, какая ошибка возвращается в браузере и выполняете отладку клиентского кода, тогда сразу становится понятно, в какой строке кода допущена ошибка.

Алла Савельева,

пытаюсь реализовать запрос:

select 
    q1.UsrCode
    , q2.Name
from 
    GeneralForm q1 
    join UsrInfoList q2 
on 
    q1.UsrInfoId = q2.Id

При моей текущей реализации этот кусок работает:
esq.addColumn("UsrInfoId.Name");
Проблема с фильтром. 

Григорий Чех,

Ок. Разбираюсь с тем как его использовать.

Григорий Чех,

а как корректно этот механизм объявить в коде?
добавил:
//перед esq
var performanceManagerLabel = "";
performanceManager.start(performanceManagerLabel + "_Init");
//сразу после фильтрации
performanceManager.stop(performanceManagerLabel + "_Init");
пишет:
'performanceManager' is not defined
 

Григорий Чех,

Нашел. 

performanceManager указать надо было.

Григорий Чех,

Верно понимаю, что performanceManager.stop по сути служит меткой для того, чтобы в браузере можно было посмотреть состояние системы на этот момент и при необходимости перескочить на следующую метку?

Алла Савельева,

Верно понимаю, что для такого запроса реализация ниже верна?
На практике без фильтра логика выдает правильное число строк, а с фильтром null.

select 
    q1.Id
    q1.UsrCode
    , q2.Name
from 
    GeneralForm q1 
    join UsrInfoList q2 
on 
    q1.UsrInfoId = q2.Id

var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
    rootSchemaName: "GeneralForm"
esq.addColumn("Id");
esq.addColumn("UsrCode");
esq.addColumn("UsrInfoId.Name");
esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(
Terrasoft.ComparisonType.EQUAL, "UsrInfoId.Name", "Инфо"));

Посмотрите в профайлере, что за SQL-запрос идёт в базу при выполнении последнего кода и потом запустите в Management Studio  его отдельно, чтобы выяснить, почему у него пустой результат.

Зверев Александр,

система в yазвании таблицы, которую пробую подцепить добавляет в начале и конце названия еще символы

SysUsrInfoListLcz. А нужна таблица была UsrInfoList. Это фича такая?

Хотя нет. Не в ней дело. Тут все хорошо.

SysUsrInfoListLcz — это автоматически сгенерированная таблица переводов названий для UsrInfoList.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Добрый день!

Пробую реализовывать запрос к данных через ESQ таким образом:

var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
                    rootSchemaName: "UsrTbl1"
                });
                esq.addColumn("Id");
                esq.addColumn("UsrPar1");esq.addColumn("UsrInfoId");
                esq.addColumn("UsrValueList.Name");//вот с такими строками уже начинается проблема

esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrValueList.Name", "значение1"));//и с такими фильтрами

 

Если нужно получить значение колонок с таблицы - rootSchemaName, то не вопрос.

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

GUID  видимо со String плохо понимают друг друга. Если ли примеры их нормального совместного использования в рамках ESQ?

Можно ли как-то понять причины неработоспособности прямых ссылок? Или хотя бы понять как с GUID быть? Даже если я значение GUID пытаюсь вставлять так, то не работает:

esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrInfoId", "337ED96B-B658-48B0-BBB6-7FACF918C735"));

У меня такой же вопрос

2 комментария
Лучший ответ

Eсли нужно получить справочную колонку, то её название нужно указывать без приставки "Id", как в схеме таблицы:

esq.addColumn("UsrInfo")

Аналогично и с фильтрами:

esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrInfo", "337ED96B-B658-48B0-BBB6-7FACF918C735"));

Но обратите внимание, что, если у Вас фильтр построен по обратным связям, то можно писать 2 способами.

1. Через Id и тогда в качестве значения фильтра указываем Id:

var shipment = this.get("BTShipment");

sampleESQ.filters.addItem(sampleESQ.createColumnFilterWithParameter(
                    this.Terrasoft.ComparisonType.EQUAL, "[BTSampInShipment:BTSampleID].BTShipment.Id", shipment.value));

2. Через справочное поле и тогда в качестве значения указывать значение справочного поля:

var shipment = this.get("BTShipment");

sampleESQ.filters.addItem(sampleESQ.createColumnFilterWithParameter(
                    this.Terrasoft.ComparisonType.EQUAL, "[BTSampInShipment:BTSampleID].BTShipment", shipment));

А вообще, чтобы понять причину ошибки нужно отладиться на стороне клиента, если запрос уходит в базу данных, то посмотреть в SQL profiler, какой запрос идет в базу и какой результат работы этого запроса.

 

В js все Guid преобразуйте к нижнему регистру

те в вашем случае напишите что то типа esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrInfoId", "337ed.....

Eсли нужно получить справочную колонку, то её название нужно указывать без приставки "Id", как в схеме таблицы:

esq.addColumn("UsrInfo")

Аналогично и с фильтрами:

esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrInfo", "337ED96B-B658-48B0-BBB6-7FACF918C735"));

Но обратите внимание, что, если у Вас фильтр построен по обратным связям, то можно писать 2 способами.

1. Через Id и тогда в качестве значения фильтра указываем Id:

var shipment = this.get("BTShipment");

sampleESQ.filters.addItem(sampleESQ.createColumnFilterWithParameter(
                    this.Terrasoft.ComparisonType.EQUAL, "[BTSampInShipment:BTSampleID].BTShipment.Id", shipment.value));

2. Через справочное поле и тогда в качестве значения указывать значение справочного поля:

var shipment = this.get("BTShipment");

sampleESQ.filters.addItem(sampleESQ.createColumnFilterWithParameter(
                    this.Terrasoft.ComparisonType.EQUAL, "[BTSampInShipment:BTSampleID].BTShipment", shipment));

А вообще, чтобы понять причину ошибки нужно отладиться на стороне клиента, если запрос уходит в базу данных, то посмотреть в SQL profiler, какой запрос идет в базу и какой результат работы этого запроса.

 

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Сделал следующие методы для валидации.

Нужно посчитать количество данных по условиям в группе фильтров. Все переменные присваивают правильные значения, кроме activeEverydayConcertCount на этапе чтения выборки. В чем проблема?

maxEverydayActive: function() {
                var invalidMessage = "";
                var activeEverydayConcertCount = 0;
                var maxActiveEverydayConcertCount = 0;
                Terrasoft.SysSettings.querySysSettingsItem("UsrMaxEverydayActiveProgram", function(value) {
                    maxActiveEverydayConcertCount = value;
                }, this);
                var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
                    rootSchemaName: "UsrConcertProgram"
                });
                esq.addAggregationSchemaColumn("Id", Terrasoft.AggregationType.COUNT, "CountEntities",
                Terrasoft.AggregationEvalType.ALL);
                
                var filterGroup = this.Terrasoft.createFilterGroup();
                
                filterGroup.add("concertsIsActive",
                this.Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrIsActive", "1"));
                filterGroup.add("performancePeriodEveryday",
                this.Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
                "UsrPerformancePeriod", "85A8C133-FF83-4290-9F69-B34EAF627F8C"));
                
                esq.filters.addItem(filterGroup);
                
                esq.getEntity(function(result) {
                        if (result.success){
                            activeEverydayConcertCount = result.entity.get("CountEntities"); - здесь не присваивается значение. Должно быть 4. По БД проверил
                        }
                }, this);
                
                if (activeEverydayConcertCount >= maxActiveEverydayConcertCount) {
                    invalidMessage = this.get("Resources.Strings.MaximumActiveEverydayConcerts");
                }
                
                return {
                    invalidMessage: invalidMessage
                };
            },
            setValidationConfig: function() {
                this.callParent(arguments);
                this.addColumnValidator("UsrIsActive", this.maxEverydayActive);
                this.addColumnValidator("UsrPerformancePeriod", this.maxEverydayActive);
            }

У меня такой же вопрос

2 комментария

Пробовал различные операции без группы фильтров, а с обычными, без условия и тд. Ничего...

 

Paul_lgb,

Добрый день. Все дело в том, что у вас даже не вызывается callback вызова getEntity (если вызывается, то это странно, возможно в вашей версии еще есть такое поведение).

Функция getEntity имеет 3 параметра:

1. primaryColumnValue

2. callback

3. scope

Функция getEntity будет возвращать вам все колонки, относящиеся к этой entity.

Пример:

getEntity("<здесь Id контакта>", function(resullt) {}) //т.е. будет фильтрация по Id контакта

Для получения количества записей, без "фильтрации" нужно использовать функцию getEntityCollection(callback), но она асинхронна, поэтому это нужно учесть.

 

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Есть такой метод:

addRecords: function(detailColumnName, segmentName, isEditableSegment) {
            var masterId = this.get("MasterRecordId");
            var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
                rootSchemaName: this.entitySchemaName
            });
            esq.addColumn(segmentName);
            esq.filters.add("masterFilter", Terrasoft.createColumnFilterWithParameter(
                this.Terrasoft.ComparisonType.EQUAL, detailColumnName, masterId));
            esq.filters.add("isDeletedFilter", Terrasoft.createColumnFilterWithParameter(
                this.Terrasoft.ComparisonType.EQUAL, "IsDeleted", false));
            esq.getEntityCollection(function(result) {
                var existsContactsCollection = [];
                if (result.success) {
                    result.collection.each(function(item) {
                        existsContactsCollection.push(item.get(segmentName).value);
                    });
                }
                var config = {
                    entitySchemaName: segmentName,
                    multiSelect: true,
                    columns: ["Type"]
                };
                
                var isAccount;
                if (segmentName === "Account") {
                    config.filters = Ext.create("Terrasoft.FilterGroup");
                    config.filters.add("first", Terrasoft.createColumnFilterWithParameter(
                        Terrasoft.ComparisonType.EQUAL, "Type", "b32e9350-aac5-47ca-89c5-b987205a510f"));
                    isAccount = true;
                }
                if (existsContactsCollection.length > 0) {

                    var existsFilter = Terrasoft.createColumnInFilterWithParameters("Id", existsContactsCollection);
                    existsFilter.comparisonType = Terrasoft.ComparisonType.NOT_EQUAL;

                    existsFilter.Name = "existsFilter";
                    if (isAccount) {
                        config.filters.add("second", existsFilter);
                    } else {
                        config.filters = existsFilter;
                    }
                }
                this.openLookup(config, function(config) {
                    methods.addRecordsCallback.call(this, config, detailColumnName, segmentName);
                }, this);
            }, this);
        },
где detailColumnName = "Campaing",
segmentName = "Product",
entitySchemaName = "ProductUsage"

В ProductUsage есть идентификатор родительского объекта (Campaing) и идентификатор продукта (Product)

Он нужен для того, чтобы лукап выводил только те записи, которых нет в детали для этого объекта и отрабатывает корректно, но вот когда на детали больше записей, чем 2100, БД SQL выдает ошибку, что конструкция IN принимает максимум 2100 параметров, поэтому я решил переделать запрос под конструкцию NotExists.

Изменил этот метод с фильтрами на следующий:

addNotExistsRecords: function(detailColumnName, segmentName, isEditableSegment) {
            var masterId = this.get("MasterRecordId");
            var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
                rootSchemaName: this.entitySchemaName
            });
            esq.addColumn(segmentName);
            esq.filters.add("masterFilter", Terrasoft.createColumnFilterWithParameter(
                this.Terrasoft.ComparisonType.EQUAL, detailColumnName, masterId));
            esq.filters.add("isDeletedFilter", Terrasoft.createColumnFilterWithParameter(
                this.Terrasoft.ComparisonType.EQUAL, "IsDeleted", false));
            esq.filters.add("isEqualsTo", Terrasoft.createColumnFilterWithParameter(
                this.Terrasoft.ComparisonType.EQUAL, "Product.Id", "ProductId"));
                
            var config = {
                entitySchemaName: segmentName,
                multiSelect: true,
                columns: ["Type"]
            };
            
            var isAccount;
            if (segmentName === "Account") {
                config.filters = Ext.create("Terrasoft.FilterGroup");
                config.filters.add("first", Terrasoft.createColumnFilterWithParameter(
                    Terrasoft.ComparisonType.EQUAL, "Type", "b32e9350-aac5-47ca-89c5-b987205a510f"));
                isAccount = true;
            }
            
            var existsFilter = Terrasoft.createNotExistsFilter("Id", esq);
            existsFilter.Name = "existsFilter";
            if (isAccount) {
                config.filters.add("second", existsFilter);
            } else {
                config.filters = existsFilter;
            }
            
            this.openLookup(config, function(config) {
                methods.addRecordsCallback.call(this, config, detailColumnName, segmentName);
            }, this);
        },

 

Однако при выполнении происходит ошибка errorCode: "NotSupportedException", message: "None", stackTrace: undefined, errors: Array(0)
Где я ошибся при построении фильтров?

По сути нужно повторить такой запрос:

select Id from Product where NOT EXISTS(select Id from ProductUsage where CampaignId = 'f39db115-d2f4-4936-b415-bf6543187463' AND IsDeleted = 'false' AND Product.Id = ProductId)
 

У меня такой же вопрос

1 комментарий
Лучший ответ

Для начала посмотрите в SQL Server профайлер, какой запрос уходит в базу данных - таким образом Вы сможете понять, в чем заключается ошибка в конкретном случае.

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

Для начала посмотрите в SQL Server профайлер, какой запрос уходит в базу данных - таким образом Вы сможете понять, в чем заключается ошибка в конкретном случае.

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

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Здравствуйте! Необходимо с помощью ESQ (не Select !) реализовать такой запрос

select Number
from Document
order by CreatedOn desc

Столкнулся с проблемой: чтоб задать сортировку по колонке, ее необходимо добавить в запрос, то есть по факту получиться такой запрос

select Number, CreatedOn
from Document
order by CreatedOn desc

В моем случае включить в выборку нужно именно одну колонку.Подскажите, как задать сортировку без добавления колонки?

У меня такой же вопрос

6 комментариев

Как вариант думаю можно попробовать создать представление (view) которое отсортирует как вам нужно и вернет нужное вам количество колонок

Максим а в чем разница сколько колонок в запросе? 2 или 1. Вы же не делаете группировку и при этом сортировку. Суть своей задачи более подробно поясните.

Суть в том, что это будет подзапрос в другом запросе и мне нужно возвращать именно одну колонку из подзапроса. Например

select
	p.Number as Number,
	(
		select top 1 d.Number
		from Document d
		where d.ProjectId = p.Id and
		d.TypeId = 'DC2768E3-8767-4E59-AD83-2DC7C3B40DAA'
		order by d.CreatedOn desc
	) as LastDocument
from Project p 

И таких подзапросов больше одного, поэтому обычный join не подходит

Тогда вам Максим нужно использовать не ESQ а Select конструкцию и тогда все у вас взлетит. Так как ESQ в конце Генерирует результирующий запрос, а SELECT вы сами описываете весь свой запрос. Я бы пошел по пути SELECT.

Власов Михаил Викторович,

 

спасибо за ответ. Насчет класса Select я знаю. Но вот выборка реализована уже с помощью Esq, и просто необходимо в запрос добавить несколько колонок в виде подзапросов. Не хочеться переписывать работающий код.

В таком случае можно построить одну большую View с колонкой-подзапросом, зарегистрировать как схему и работать в ESQ с ней.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Здравствуйте! Подскажите, а как добавить в фильтры серверного EntitySchemaQuery подзапрос или где в системе можно найти пример? На SQL запрос выглядит следующим образом:

SELECT
   * 
FROM
   [Contract] 
WHERE
   StartDate = (
        SELECT MAX(c.StartDate)
        FROM Premises p
        JOIN PremisesInContract pic ON p.Id = pic.PremisesId
        JOIN Contract c ON spic.ContractId = c.Id
        WHERE p.Id = --@someparameter
   )

 

У меня такой же вопрос

1 комментарий
Лучший ответ

Добрый день, похожая ситуация обсуждалась тут https://community.terrasoft.ru/questions/ispolzovanie-kollekcii-v-select

Добрый день, похожая ситуация обсуждалась тут https://community.terrasoft.ru/questions/ispolzovanie-kollekcii-v-select

Войдите или зарегистрируйтесь, чтобы комментировать