System.Linq.Dynamic - 在WHERE语句中使用SELECT

时间:2017-04-20 18:41:38

标签: c# sql linq dynamic-linq

我需要使用System.Linq.Dynamic动态生成SQL查询,如下所示:

SELECT 
    [Extent1].[FromRevision] AS [FromRevision], 
    [Extent1].[Field1] AS [Field1], 
    [Extent1].[TillRevision] AS [TillRevision], 
    [Extent1].[Field2] AS [Field2], 
    [Extent1].[Date1] AS [Date1], 
    [Extent1].[LastChangeDate] AS [LastChangeDate], 
    [Extent1].[Field3] AS [Field3]
    FROM [log].[MyTable] AS [Extent1]
    WHERE (([Extent1].[FromRevision] <= @p__linq__0) AND ([Extent1].[TillRevision] > @p__linq__1) AND 
    ( NOT EXISTS (SELECT 
        1 AS [C1]
        FROM [log].[MyTable] AS [Extent2]
        WHERE ([Extent2].[Field1] = [Extent1].[Field1]) AND ([Extent2].[FromRevision] <= @p__linq__2) AND ([Extent2].[TillRevision] > @p__linq__3)
    )))

上面的代码由Linq为通用IQueryable生成,如下所示:

query.Where(o =>
            //ADDED
            (   o.FromRevision <= tillRevision &&
                o.TillRevision > tillRevision &&
                !query.Any(o1 =>
                    o1.Uid == o.Uid &&
                    o1.FromRevision <= fromRevision &&
                    o1.TillRevision > fromRevision)
            )

但是可以使用Dynamic Linq得到相同的结果,相同的SELECT结果而不是通用的IQueryable吗?

1 个答案:

答案 0 :(得分:2)

您可以使用可选的params object[] values参数将一些参数传递给动态查询(例如querytillRevisionfromRevision)。然后,您可以根据字符串的位置在字符串中引用它们@0@1@2

要访问范围内的当前范围变量,您可以使用it或不使用任何内容。它将等同于您的o变量。重要的细节是,当您输入嵌套范围(例如Any)时,在该范围内it或者什么都不会引用您的o1变量。要访问外部变量,您应该使用outerIt

以下是您的查询的动态LINQ等价物,希望您能弄清楚如何动态构建它:

var result = query.Where(
    "FromRevision <= @0 && TillRevision > @0 && !@2.Any(Uid == outerIt.Uid && FromRevision <= @1 && TillRevision > @1)",
    tillRevision, // @0
    fromRevision, // @1,
    query // @2
);