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

System.Linq.Dynamic - use SELECT inside WHERE statement

我需要像这样使用 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 而不是通用 IQueryable 的相同 SELECT 结果?

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

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

这是与您的查询等效的 Dynamic LINQ,希望您能弄清楚如何动态构建它:

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