Как создать дерево выражений Dynami c Linq VB.net - PullRequest
0 голосов
/ 20 апреля 2020

Мне нужно воспроизвести этот запрос как динамическое c выражение Linq, оно должно выглядеть следующим образом, когда оно достигает SQL трассировки сервера. Я не смог найти никакой документации, которая помогла бы собрать это воедино. Мне удалось выполнить динамические c запросы Where, Order By и Count, но ничего подобного.

Я уже знаю, как выполнить предложение where и order by, мне нужна конкретная c помощь по созданию выражение для выполнения следующих частей:

COUNT(*) OVER ()         AS ROW_COUNT

OFFSET 0 ROWS FETCH NEXT 250 ROW ONLY

Конечный результат должен выглядеть следующим образом в трассировке профилировщика запросов.

    EXEC sys.sp_executesql
    N'SELECT
    COUNT(*) OVER ()         AS ROW_COUNT
   ,[t0].[Trans Date]        AS [Trans_Date]
   ,[t0].[Trans Time]        AS [Trans_Time]
   ,[t0].[Trans Type]        AS [Trans_Type]
   ,[t0].[Transaction]       AS [Transaction]
   ,[t0].[Misc Info]         AS [Misc_Info]
   ,[t0].[Orig License Qty]  AS [Orig_License_Qty]
   ,[t0].[Chg Qty Total]     AS [Chg_Qty_Total]
   ,[t0].[Chg Qty On Hold]   AS [Chg_Qty_On_Hold]
   ,[t0].[New License Qty]   AS [New_License_Qty]
   ,[t0].[Total Qty of Item] AS [Total_Qty_of_Item]
   ,[t0].[User Name]         AS [User_Name]
   ,[t0].[Order Num]         AS [Order_Num]
   ,[t0].[Line No]           AS [Line_No]
   ,[t0].[Receiver ID]       AS [Receiver_ID]
   ,[t0].[Item ID]           AS [Item_ID]
   ,[t0].[Item Description]  AS [Item_Description]
   ,[t0].[Type]
   ,[t0].[RFID]
   ,[t0].[License No]        AS [License_No]
   ,[t0].[Old Loc]           AS [Old_Loc]
   ,[t0].[New Loc]           AS [New_Loc]
   ,[t0].[Pick Container ID] AS [Pick_Container_ID]
   ,[t0].[Category ID]       AS [Category_ID]
   ,[t0].[Reason]
   ,[t0].[Device RF IP]      AS [Device_RF_IP]
   ,[t0].[User ID]           AS [User_ID]
   ,[t0].[Custom Data 1]     AS [Custom_Data_1]
   ,[t0].[Custom Data 2]     AS [Custom_Data_2]
   ,[t0].[Custom Data 3]     AS [Custom_Data_3]
   ,[t0].[Custom Data 4]     AS [Custom_Data_4]
   ,[t0].[Custom Data 5]     AS [Custom_Data_5]
   ,[t0].[Custom Data 6]     AS [Custom_Data_6]
FROM
    [wms].[vwAuditLogNew] AS [t0]
WHERE
    ([t0].[Orig License Qty] IS NOT NULL)
    AND ([t0].[Trans Date] = @p0)
ORDER BY
    [t0].[Trans Date] DESC
   ,[t0].[Trans Time] DESC OFFSET 0 ROWS FETCH NEXT 250 ROW ONLY'
,N'@p0 datetime'
,@p0 = '2020-04-01 00:00:00';

Вот мой пример linqpad, AdvancedSearchClass просто создает WhereClauseExpression.

Dim Queryable As IQueryable(Of vwAuditLogNew) = vwAuditLogNews.AsQueryable
Console.WriteLine(Queryable.ToString())
Dim MasterPE As ParameterExpression = Expression.Parameter(GetType(vwAuditLogNew), GetType(vwAuditLogNew).Name)
Console.WriteLine(MasterPE.ToString)
Dim source = Expression.Parameter(GetType(vwAuditLogNew), "p")
Console.WriteLine(source.ToString())
Dim tbl=Queryable.Expression
Console.WriteLine(tbl.ToString)
Dim dp=Expression.PropertyOrField(source,"Trans_Date")
Console.WriteLine(dp.ToString())
Dim CountMethod =Gettype(Enumerable).GetMethods().First(Function(x) x.Name="Count" AndAlso x.GetParameters.Length=1).MakeGenericMethod(GetType(vwAuditLogNew))
console.WriteLine(CountMethod.ToString)
Dim AdvancedSearchClass = New AdvancedSearchClass(Of vwAuditLogNew) With {
            .Queryable = vwAuditLogNews
        }
Dim PredicateBody As Expression = AdvancedSearchClass.WhereIsNotEmpty("Orig_License_Qty")
Dim whereClauseExpression As Expression = AdvancedSearchClass.WhereClauseExpression(PredicateBody)

Dim cnt=Expression.Call(CountMethod,whereClauseExpression)

Console.WriteLine(cnt.ToString)

Dim qry=Queryable.Provider.CreateQuery(cnt)
Console.WriteLine(qry.ToString())
...