как сопоставить столбец, если существует в противном случае пустым - PullRequest
0 голосов
/ 22 июня 2019

Я пытаюсь сопоставить свойство с формулой, чтобы выбрать значение, если столбец существует, в противном случае значение по умолчанию

Я попробовал следующее

mapper.Map(x => x.GroupId).Formula("(select case when exists (select * from INFORMATION_SCHEMA.COLUMNS SYS_COLS_TBL WHERE SYS_COLS_TBL.TABLE_NAME ='Azure' AND SYS_COLS_TBL.COLUMN_NAME = 'GroupId') then this_.GroupId else '' end)");

Я получаю ошибку SqlException: недопустимое имя столбца 'GroupId'.

Ответы [ 2 ]

0 голосов
/ 25 июня 2019

Оператор SQL требует, чтобы все ссылки на таблицы и столбцы существовали.Поэтому вы получаете Invalid column name 'GroupId' ошибку.

Обычный способ сделать что-то подобное - использовать динамический sql (sp_executesql @sql):

DECLARE @sql NVARCHAR(MAX) = '
SELECT '+
    (CASE WHEN EXISTS (SELECT *
                       FROM INFORMATION_SCHEMA.COLUMNS 
                       WHERE TABLE_SCHEMA = 'dbo' AND --assuming the schema is dbo
                             TABLE_NAME = 'Azure' AND
                             COLUMN_NAME = 'GroupId'
                      )
          then 'GroupId'
          else 'NULL as GroupId'
     end) + '
FROM Azure';

exec sp_executesql @sql

Но это не сработаетпотому что вы уже находитесь в контексте оператора SQL и там невозможно внедрить динамический sql.

Для решения проблемы есть несколько решений:

  1. Правильное решение: создайте отсутствующие столбцы в базе данных.

  2. Болезненное решение: сопоставьте объект хранимым процедурам, которые будут выполнять динамический SQL, аналогичный приведенному выше.

  3. Безумно болезненное решение: сопоставьте возможные пропущенные столбцы как обычно.Перед созданием фабрики - проанализируйте свою модель и либо удалите сопоставлений для отсутствующих столбцов, либо измените их сопоставления на формулы.Это будет похоже на Configuration.ValidateSchema метод NHibernate, но вместо того, чтобы выдавать ошибки - вам нужно будет удалить эти столбцы из сопоставления.

0 голосов
/ 24 июня 2019

Этот оператор SQL вернет все таблицы, которые имеют имя Azure

select * from INFORMATION_SCHEMA.COLUMNS SYS_COLS_TBL 
 WHERE SYS_COLS_TBL.TABLE_NAME ='Azure' 
   AND SYS_COLS_TBL.COLUMN_NAME = 'GroupId'

, но может быть, например, две такие таблицы ... но в разных схемах .И если это произойдет, мы можем запросить dbo.Azure .. в то время как SomeOtherSchema.Azure имеет столбец GroupId.Это исправит это:

select * from INFORMATION_SCHEMA.COLUMNS SYS_COLS_TBL 
 WHERE SYS_COLS_TBL.TABLE_NAME ='Azure' 
   AND SYS_COLS_TBL.COLUMN_NAME = 'GroupId'
   AND SYS_COLS_TBL.TABLE_SCHEMA = 'dbo'

Также для поддержки более сложных запросов (объединений JOIN) удалите this _. :

вместо:

then this_.GroupId else '' end)

использование:

then GroupId else '' end)

NHibernate предоставит правильный псевдоним на основе контекста

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...