EntitySpaces/C#: Как использовать подзапрос в операторе CASE?
Я пытаюсь эмулировать фрагмент SQL с помощью EntitySpaces. Я почти готов вернуться к хорошему старому сырому SQL, но лучше научусь делать это правильно...
Это SQL, который я пытаюсь воспроизвести:
SELECT
CASE WHEN GL.SOURCE = 'AP' THEN (SELECT COMPANY FROM VEND WHERE VEND.ID = GL.ID)
WHEN GL.SOURCE = 'AR' THEN (SELECT COMPANY FROM CUST WHERE CUST.ID = GL.ID)
WHEN GL.SOURCE = 'SB' THEN (SELECT COMPANY FROM SBMASTER WHERE SBMASTER.ID = GL.ID)
ELSE '' END AS COMPANY
FROM GL
LEFT OUTER JOIN ACCT ON GL.ACCT = ACCT.ACCT
Я немного поигрался с кодом без удачи. Вот что у меня есть на данный момент:
GlQuery qryGl = new GlQuery("qryGl");
AcctQuery qryAcct = new AcctQuery("qryAcct");
AcctQuery qryAcctSub = new AcctQuery("qryAcct");
VendQuery qryVendSub = new VendQuery("qryVend");
CustQuery qryCustSub = new CustQuery("qryCust");
SbmasterQuery qrySbmasterSub = new SbmasterQuery("qrySbmaster");
qryGl.Select
(
qryGl.Source.Case()
.When("AP").Then(qryVendSub.Select(qryVendSub.Company).Where(qryVendSub.Id == qryGl.Id))
.When("AR").Then(qryCustSub.Select(qryCustSub.Company).Where(qryCustSub.Id == qryGl.Id))
.When("SB").Then(qrySbmasterSub.Select(qrySbmasterSub.Company).Where(qrySbmasterSub.Id == qryGl.Id))
.Else("")
.End().As("COMPANY")
);
qryGl.LeftJoin(qryAcct).On(qryGl.Acct == qryAcct.Acct);
что дает мне следующий (явно неправильный!) вывод:
SELECT
[COMPANY] = CASE
WHEN 'AP' THEN MyProject.Com.Data.VendQuery
WHEN 'AR' THEN MyProject.Com.Data.CustQuery
WHEN 'SB' THEN MyProject.Com.Data.SbmasterQuery
ELSE ''
END
FROM [GL] qryGl
LEFT JOIN [ACCT] qryAcct ON qryGl.[ACCT] = qryAcct.[ACCT]
Буду признателен за любую помощь в получении этого подзапроса SQL в оператор case!
Довольно плохо знаком с EntitySpaces, так что надеюсь, что это просто что-то простое, что я пропустил...
ура
1 ответ
Рассматривая методы, доступные для Then()
метод, я думаю, что это не возможно.
- E сть
Then(object)
, к которому относится ваш запрос, и EntitySpaces преобразует его в строковый литерал и помещает его непосредственно в окончательный запрос. - E сть
Then(esQueryItem)
который будет работать с одним столбцом, таким какqryGl.Source
, - Наконец, есть
Then(esExpression)
, Я немного запутался в этом, но я думаю, что он используется для размещения параметров выбора операторов, так что, вероятно, он тоже не будет работать для вас.
Я думаю, что вам нужно это Then(DynamicQuery)
или что-то подобное.
Поскольку EntitySpaces является открытым исходным кодом, теперь вы можете добавить эту перегрузку самостоятельно, а затем изменить поставщиков данных, которые вы используете, для работы с новой опцией подзапроса. Я сделал аналогичное изменение для обработки подзапросов в других местах, и это было не так уж плохо для задачи. Самой простой частью на самом деле являются провайдеры, потому что, как только вы определите, что имеете дело с подзапросом, вам, по сути, нужно только снова вызвать вершину стека для вашего нового встроенного запроса, прежде чем продолжить.
Однако из того, что я видел выше, я бы сказал, что если вы хотите избежать взлома кода EntitySpaces, вам, вероятно, придется обратиться к жестко закодированному запросу. Майк из EntitySpaces всегда рекомендовал просмотр базы данных или хранимую процедуру для таких пользовательских загрузок.
Также: имейте в виду, что если вы создаете ручные запросы на стороне клиента, вы все равно можете избежать жесткого кодирования большей части запроса, используя [TableName]Metadata.ColumnNames.[ColumnNameConstant].