Псевдоним таблицы потерян при использовании объединений с SqlExpressionSelectFilter

#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 .