#servicestack #ormlite-servicestack
#servicestack #ormlite-servicestack
Вопрос:
У меня ситуация, когда записи должны быть исключены в зависимости от значения в связанной таблице. При использовании объединений с SqlExpressionSelectFilter сгенерированный SQL не будет использовать псевдоним таблицы для части запроса. Я использую ServiceStack 5.5.
OrmLiteConfig.SqlExpressionSelectFilter = q => {
if (q.ModelDef.ModelType.HasInterface(typeof(IJoinFilter))) {
q.LeftJoin<IJoinFilter, FirstTable>((f, j) => f.FirstTableId == j.Id)
.Where<FirstTable>(j => j.Deleted != true);
}
};
И просто выбираем из него с помощью:
db.Select(db.From<SecondTable>().Where<SecondTable>(x => x.Id == 1));
Это генерирует что-то вроде:
SELECT SecondTable.Id, SecondTable.FirstTableId, SecondTable.Deleted
FROM SecondTable
LEFT JOIN FirstTable ON (SecondTable.FirstTableId = FirstTable.Id)
WHERE (Id = 1) AND (FirstTable.Deleted <> 1)
Обратите внимание, что идентификатор в предложении where не предваряется «SecondTable». Существуют также случаи, для которых предложение select не будет включать псевдонимы.
Поддерживаются ли объединения в фильтрах выбора? Есть ли рекомендуемый способ, которым я должен использовать этот глобальный фильтр вместо этого?
Я создал здесь краткое воспроизведение: https://github.com/TheScobey/OrmliteSelectFilterIssue
Ответ №1:
Применяется SqlExpressionSelectFilter
после создания выражения, поэтому оно не сможет повлиять на предыдущие выражения, вы можете попробовать присвоить источнику из таблицы псевдоним с помощью:
db.Select(db.From<SecondTable>(db.TableAlias(nameof(SecondTable)))
.Where<SecondTable>(x => x.Id == 1));
Альтернативой является принудительное включение в запрос префикса таблицы в запросах, например:
var q = db.From<SecondTable>();
q.PrefixFieldWithTableName = true;
q.Where<SecondTable>(x => x.Id == 1);
Комментарии:
1. К сожалению, запрос в конечном итоге использовал пользовательский псевдоним в базовом выражении, но псевдоним по умолчанию для объединения: SELECT st.Id , st.FirstTableId, st.Удалено ИЗ SecondTable st ОСТАЛОСЬ ПРИСОЕДИНИТЬСЯ К FirstTable ON (SecondTable. FirstTableId = FirstTable . Id) ГДЕ (st. Id = @0) И (FirstTable. Удалено <> @1)
2. @Will У него нет конкретного типа в SelectFilter чтобы иметь возможность знать, какой псевдоним таблицы он может использовать, вы можете использовать то же имя, что и таблица для псевдонима, например, вот живой пример на Gistlyn .
3. Может ли PrefixFieldWithTableName применяться ко всем запросам для конкретной таблицы?
4. @Will Самым простым способом было бы обернуть его в свой собственный метод ext (например
FromTable<T>
), который инициализирует запрос с вашими предпочтениями. Я только что добавил дополнительные параметры глобальной конфигурации, которые вы можете сделать сOrmLiteConfig.IncludeTablePrefixes = true
помощью иOrmLiteConfig.SqlExpressionInitFilter = q => q.PrefixFieldWithTableName = true
. Это изменение доступно в последней версии 5.5.1, которая теперь доступна в MyGet .