Сообщение Re: Репозиторий. Как сделать поиск с исключением от 06.11.2025 13:41
Изменено 06.11.2025 13:47 pilgrim_
Re: Репозиторий. Как сделать поиск с исключением
Здравствуйте, zelenprog, Вы писали:
Z>Объясню зачем нужен такой "сложный" поиск.
Z>Грубо — в зависимости от того критерия, по которому отобраны сущности, выполняются разные обработки над выборками.
Z>У каждого критерия есть признак "вес достоверности".
Z>Например, самый "достоверный" — это Критреий-1. Юрлица, найденные по этому критерию являются "достоверными" и они обрабатываются по одному алгоритму.
Z>Юрлица, найденные по следующему критерию, менее достоверные, их надо обрабатывать по алгоритму-2. И т.д.
Z>Проблема в том, что результаты поиска по каждому критерию пересекающиеся.
Z>То есть одно и тоже юрлицо может попасть в выборку и по Критерию-1 и по Критерию-2 и по другим Критериям.
Z>Но обработано юрлицо должно быть по наиболее "достоверному" Критерию и соответствующему алгоритму.
Z>То есть, если юрлицо попало в выборку по более "достоверному" Критерию-1, то оно должно быть обработано по Алгоритму-1. Нет смысла рассматривать это юрлицо по другим Критериям. Поэтому из поиска по другим Критериям это юрлицо надо как-то исключить.
Z>Вопрос: как при поиске по следующему в массиве Критерию-(n) "отсечь" из результата поиска те сущности, которые были найдены при поиске по предыдущим Критериям?
1) Уже написали про составной критерий, а чтобы узнать по какому конкретно критерию выла выбрана сущность, в SQL можно использовать в селекте конструкцию case/when/then, где сравнения критериев указаны в порядке убывания "веса", в LINQ аналог — тернарный условный оператор (?: ) в селекте, тут главнео чтобы используемый linq-провайдер поддерживал генерацию case/when/then по этому оператору. Т.е. критерии должны быть продублированны как в where, так и в select case/when/then (?: ).
Имхо это самый эффектиный способ, елси кол-во критерией не очень большое (десятки, может сотни, оптимальное кол-во определять в результате тестирования).
2) Выборка по одному критерию в цикле (критерии отсортированны по убывания "веса"):
На каждой итерации выбираем только ID (PK) сущностей соотв. критерию, складываем напр. в HashTable (ключ ID, значение — "вес") — добавляем только несуществующие в хэштаблице.
Затем для накопленных ID читаем сами сущности.
3) Выборка по одному критерию в цикле (критерии отсортированны по убывания "веса"), SQL база/временная таблица:
Создаём временную таблицу с уникальным индексом по ID и флагом ignore duplicates (база должна поддерживать такую фичу), одним SQL запросом (select/insert) вставляем сущности/вес в эту таблицу. Тут опять же, используемый linq-провайдер должен поддерживать генерацию такого sql (linq2db умеет).
Затем из этой таблицы читаем сами сущности и их вес.
Z>Посоветуйте плиз как сделать грамотно в русле разделения слоев и "чистой архитектуры".
Всё выше описаннео расположить в репозитории — чище некуда
Z>Объясню зачем нужен такой "сложный" поиск.
Z>Грубо — в зависимости от того критерия, по которому отобраны сущности, выполняются разные обработки над выборками.
Z>У каждого критерия есть признак "вес достоверности".
Z>Например, самый "достоверный" — это Критреий-1. Юрлица, найденные по этому критерию являются "достоверными" и они обрабатываются по одному алгоритму.
Z>Юрлица, найденные по следующему критерию, менее достоверные, их надо обрабатывать по алгоритму-2. И т.д.
Z>Проблема в том, что результаты поиска по каждому критерию пересекающиеся.
Z>То есть одно и тоже юрлицо может попасть в выборку и по Критерию-1 и по Критерию-2 и по другим Критериям.
Z>Но обработано юрлицо должно быть по наиболее "достоверному" Критерию и соответствующему алгоритму.
Z>То есть, если юрлицо попало в выборку по более "достоверному" Критерию-1, то оно должно быть обработано по Алгоритму-1. Нет смысла рассматривать это юрлицо по другим Критериям. Поэтому из поиска по другим Критериям это юрлицо надо как-то исключить.
Z>Вопрос: как при поиске по следующему в массиве Критерию-(n) "отсечь" из результата поиска те сущности, которые были найдены при поиске по предыдущим Критериям?
1) Уже написали про составной критерий, а чтобы узнать по какому конкретно критерию выла выбрана сущность, в SQL можно использовать в селекте конструкцию case/when/then, где сравнения критериев указаны в порядке убывания "веса", в LINQ аналог — тернарный условный оператор (?: ) в селекте, тут главнео чтобы используемый linq-провайдер поддерживал генерацию case/when/then по этому оператору. Т.е. критерии должны быть продублированны как в where, так и в select case/when/then (?: ).
Имхо это самый эффектиный способ, елси кол-во критерией не очень большое (десятки, может сотни, оптимальное кол-во определять в результате тестирования).
2) Выборка по одному критерию в цикле (критерии отсортированны по убывания "веса"):
На каждой итерации выбираем только ID (PK) сущностей соотв. критерию, складываем напр. в HashTable (ключ ID, значение — "вес") — добавляем только несуществующие в хэштаблице.
Затем для накопленных ID читаем сами сущности.
3) Выборка по одному критерию в цикле (критерии отсортированны по убывания "веса"), SQL база/временная таблица:
Создаём временную таблицу с уникальным индексом по ID и флагом ignore duplicates (база должна поддерживать такую фичу), одним SQL запросом (select/insert) вставляем сущности/вес в эту таблицу. Тут опять же, используемый linq-провайдер должен поддерживать генерацию такого sql (linq2db умеет).
Затем из этой таблицы читаем сами сущности и их вес.
Z>Посоветуйте плиз как сделать грамотно в русле разделения слоев и "чистой архитектуры".
Всё выше описаннео расположить в репозитории — чище некуда
Re: Репозиторий. Как сделать поиск с исключением
Здравствуйте, zelenprog, Вы писали:
Z>Объясню зачем нужен такой "сложный" поиск.
Z>Грубо — в зависимости от того критерия, по которому отобраны сущности, выполняются разные обработки над выборками.
Z>У каждого критерия есть признак "вес достоверности".
Z>Например, самый "достоверный" — это Критреий-1. Юрлица, найденные по этому критерию являются "достоверными" и они обрабатываются по одному алгоритму.
Z>Юрлица, найденные по следующему критерию, менее достоверные, их надо обрабатывать по алгоритму-2. И т.д.
Z>Проблема в том, что результаты поиска по каждому критерию пересекающиеся.
Z>То есть одно и тоже юрлицо может попасть в выборку и по Критерию-1 и по Критерию-2 и по другим Критериям.
Z>Но обработано юрлицо должно быть по наиболее "достоверному" Критерию и соответствующему алгоритму.
Z>То есть, если юрлицо попало в выборку по более "достоверному" Критерию-1, то оно должно быть обработано по Алгоритму-1. Нет смысла рассматривать это юрлицо по другим Критериям. Поэтому из поиска по другим Критериям это юрлицо надо как-то исключить.
Z>Вопрос: как при поиске по следующему в массиве Критерию-(n) "отсечь" из результата поиска те сущности, которые были найдены при поиске по предыдущим Критериям?
1) Уже написали про составной критерий, а чтобы узнать по какому конкретно критерию выла выбрана сущность, в SQL можно использовать в селекте конструкцию case/when/then, где сравнения критериев указаны в порядке убывания "веса", в LINQ аналог — тернарный условный оператор (?: ) в селекте, тут главнео чтобы используемый linq-провайдер поддерживал генерацию case/when/then по этому оператору. Т.е. критерии должны быть продублированны как в where, так и в select case/when/then (?: ).
Имхо это самый эффектиный способ, елси кол-во критерией не очень большое (десятки, может сотни, оптимальное кол-во определять в результате тестирования).
2) Выборка по одному критерию в цикле (критерии отсортированны по убывания "веса"):
На каждой итерации выбираем только ID (PK) сущностей соотв. критерию, складываем напр. в HashTable (ключ ID, значение — "вес") — добавляем только несуществующие в хэштаблице.
Затем для накопленных ID читаем сами сущности.
3) Выборка по одному критерию в цикле (критерии отсортированны по убывания "веса"), SQL база/временная таблица:
Создаём временную таблицу с уникальным индексом по ID и флагом ignore duplicates (база должна поддерживать такую фичу), одним SQL запросом (select/insert) вставляем сущности/вес в эту таблицу. Тут опять же, используемый linq-провайдер должен поддерживать генерацию такого sql (linq2db умеет).
Затем из этой таблицы читаем сами сущности и их вес.
upd: Для эффективности выборки по критериям таблицы должны иметь соотв. индексы дял используемых в критериях полей.
Z>Посоветуйте плиз как сделать грамотно в русле разделения слоев и "чистой архитектуры".
Всё выше описаннео расположить в репозитории — чище некуда
Z>Объясню зачем нужен такой "сложный" поиск.
Z>Грубо — в зависимости от того критерия, по которому отобраны сущности, выполняются разные обработки над выборками.
Z>У каждого критерия есть признак "вес достоверности".
Z>Например, самый "достоверный" — это Критреий-1. Юрлица, найденные по этому критерию являются "достоверными" и они обрабатываются по одному алгоритму.
Z>Юрлица, найденные по следующему критерию, менее достоверные, их надо обрабатывать по алгоритму-2. И т.д.
Z>Проблема в том, что результаты поиска по каждому критерию пересекающиеся.
Z>То есть одно и тоже юрлицо может попасть в выборку и по Критерию-1 и по Критерию-2 и по другим Критериям.
Z>Но обработано юрлицо должно быть по наиболее "достоверному" Критерию и соответствующему алгоритму.
Z>То есть, если юрлицо попало в выборку по более "достоверному" Критерию-1, то оно должно быть обработано по Алгоритму-1. Нет смысла рассматривать это юрлицо по другим Критериям. Поэтому из поиска по другим Критериям это юрлицо надо как-то исключить.
Z>Вопрос: как при поиске по следующему в массиве Критерию-(n) "отсечь" из результата поиска те сущности, которые были найдены при поиске по предыдущим Критериям?
1) Уже написали про составной критерий, а чтобы узнать по какому конкретно критерию выла выбрана сущность, в SQL можно использовать в селекте конструкцию case/when/then, где сравнения критериев указаны в порядке убывания "веса", в LINQ аналог — тернарный условный оператор (?: ) в селекте, тут главнео чтобы используемый linq-провайдер поддерживал генерацию case/when/then по этому оператору. Т.е. критерии должны быть продублированны как в where, так и в select case/when/then (?: ).
Имхо это самый эффектиный способ, елси кол-во критерией не очень большое (десятки, может сотни, оптимальное кол-во определять в результате тестирования).
2) Выборка по одному критерию в цикле (критерии отсортированны по убывания "веса"):
На каждой итерации выбираем только ID (PK) сущностей соотв. критерию, складываем напр. в HashTable (ключ ID, значение — "вес") — добавляем только несуществующие в хэштаблице.
Затем для накопленных ID читаем сами сущности.
3) Выборка по одному критерию в цикле (критерии отсортированны по убывания "веса"), SQL база/временная таблица:
Создаём временную таблицу с уникальным индексом по ID и флагом ignore duplicates (база должна поддерживать такую фичу), одним SQL запросом (select/insert) вставляем сущности/вес в эту таблицу. Тут опять же, используемый linq-провайдер должен поддерживать генерацию такого sql (linq2db умеет).
Затем из этой таблицы читаем сами сущности и их вес.
upd: Для эффективности выборки по критериям таблицы должны иметь соотв. индексы дял используемых в критериях полей.
Z>Посоветуйте плиз как сделать грамотно в русле разделения слоев и "чистой архитектуры".
Всё выше описаннео расположить в репозитории — чище некуда