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

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 профайлер, какой запрос уходит в базу данных - таким образом Вы сможете понять, в чем заключается ошибка в конкретном случае.

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

Показать все комментарии

Есть sql-запрос вида:

select *

from Table T

where T.ProjectId = @ProjectId

    and not exists (select * from Table T1

                    where T1.ContactId = @ContactId

                        and T1.ParameterId = T.ParameterId)

Использование метода CreateFilterWithParameters() позволяет построить параметризированный запрос, но только exists:

var esqCardBlock = new EntitySchemaQuery(userConnection.EntitySchemaManager, "Table");

esqCardBlock.AddAllSchemaColumns();

var CardBlockFilters = esqCardBlock.Filters;                  CardBlockFilters.Add(esqCardBlock.CreateFilterWithParameters(FilterComparisonType.Equal,

                        "Project", projectId));                CardBlockFilters.Add(esqCardBlock.CreateFilterWithParameters(FilterComparisonType.Equal,

                        "[Table:Parameter:Parameter].Contact", contact));

Если же использовать CreateNotExistsFilter(), то не понятно, куда добавлять значение параметра @ContactId.

Какой всё-таки метод использовать для построения параметризированного запроса Not Exists?

Нравится

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

Алла, возможно, такое получится при помощи выставления группе фильтров свойства .IsNot = true;

Как тут:

			var esq = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "Activity");
			esq.AddAllSchemaColumns();
			esq.Filters.Add(esq.CreateFilterWithParameters(FilterComparisonType.Equal, "Owner", currentUserId));
			esq.Filters.Add(esq.CreateFilterWithParameters(FilterComparisonType.Greater, "ModifiedOn", LastSyncDate));
			if (IsFirstSync) {
				esq.Filters.Add(esq.CreateFilterWithParameters(FilterComparisonType.Greater, "DueDate", Today));
			}
			esq.Filters.Add(esq.CreateFilterWithParameters(FilterComparisonType.Equal, "ShowInScheduler", true));
			var filtersByExisting = new EntitySchemaQueryFilterCollection(esq);
			filtersByExisting.IsNot = true;
			var notExFilter = esq.CreateFilterWithParameters(
				FilterComparisonType.IsNotNull,
				"[ActivityCorrespondence:Activity].SourceActivityId");
			filtersByExisting.Add(notExFilter);
			filtersByExisting.Add(esq.CreateFilterWithParameters(FilterComparisonType.Equal,
				"[ActivityCorrespondence:Activity].SourceAccount.Id", SourceAccountId));
			esq.Filters.Add(filtersByExisting);
			esq.Filters.Add(esq.CreateFilterWithParameters(FilterComparisonType.LessOrEqual, "CreatedOn", CurrentSyncDateTime));
			var entityCollection = esq.GetEntityCollection(UserConnection);

 

Саша,

спасибо за ответ. Я тоже уже думала так сделать, попробую и напишу о результате smiley

Саша,

таким способом, как ты предложил, получилось построить нужный фильтр.

Ещё вопрос: почему в документации на академии написано, что метод CreateFilterWithParameters перегруженный https://academy.terrasoft.ru/documents/technic-sdk/7-11/dobavlenie-vych…;Что имеется ввиду?

Алла, у меня по этой ссылке нет слов «перегруженный»  и «CreateFilterWithParameters».

Ошибка, речь идет об этой ссылке: https://academy.terrasoft.ru/documents/technic-sdk/7-11/ispolzovanie-en…

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

А подскажите, пожалуйста, есть ли аналог ".IsNot = true" в entitySchemaQuery на стороне клиента?

И если нет, то как по другому в js можно построить подобный фильтр?

См. верхний ответ тут.

Показать все комментарии