如果我在不使用 CloseExpression 的情况下使用 AndExpression 会发生什么

What happens if I use `AndExpression` without `CloseExpression`

我有这个亚音速查询:

Select.AllColumnsFrom<Data.Group>()
    .Where(Data.Group.GroupIDColumn).IsNotEqualTo(m_sRootGroupID)
    .AndExpression(Data.Group.Columns.OwnerPersonID).IsEqualTo(gUserID)
    .OrExpression(Data.Group.Columns.OwnerPersonID).IsEqualTo(gUserContextID)
    .AndExpression(Data.Group.Columns.IsCallList).IsEqualTo(true)
    .CheckLogicalDelete().ExecuteTypedList<Groups>();

乍一看,好像是之前的开发者把AndExpression误认为是And了。我知道 AndExpression 将前面的语句括在括号内。

上面的subsonic查询是如何翻译成SQL的?

这就是我的想法:

SELECT * 
FROM tblGroups
WHERE GroupID <> m_sRootGroupID
  AND ( --first [AndExpression]
    OwnerPersonID = `gUserID
    OR ( -- [OrExpression]
        OwnerPersonID = gUserContextID
        AND ( -- second [AndExpression]
             IsCallList = true
        )
    )
) -- first [AndExpression]
AND ISNULL(IsDeleted,0) = 0

如果没有 CloseExpression,如何处理 ..Expression

要获取发出的 sql 只需调用查询的 ToString 方法,这将调用 BuildSqlStatement。

正如@MikeWalsh 在他的 中所指出的,调用 .ToString() 显示了亚音速查询在转换为 SQL.

时的样子

因此,上面的代码可以翻译成:

SELECT * --subsonic specifies all columns

 FROM [dbo].[tblGroups]
 WHERE [dbo].[tblGroups].[GroupID] <> @GroupID0
 AND ([dbo].[tblGroups].[OwnerPersonID] = @OwnerPersonID1
)
 OR ([dbo].[tblGroups].[OwnerPersonID] = @OwnerPersonID3
)
 AND ([dbo].[tblGroups].[IsCallList] = @IsCallList5
)
 AND ([dbo].[tblGroups].[IsDeleted] IS NULL OR [dbo].[tblGroups].[IsDeleted] = 0)

这告诉我们调用 AndExpression/OrExpression 时不带 CloseExpression,subsonic 假定括号中的 AND 语句中只有一个条件,因此:

.AndExpression(Data.Group.Columns.OwnerPersonID).IsEqualTo(gUserID)

翻译成: AND ([dbo].[tblGroups].[OwnerPersonID] = @OwnerPersonID1)


编辑:

我就是这么想的。然而,当使用这个亚音速查询时:

Select.AllColumnsFrom<Data.Group>()
    .Where(Data.Group.GroupIDColumn).IsNotEqualTo(m_sRootGroupID)
    .AndExpression(Data.Group.Columns.OwnerPersonID).IsEqualTo("someownerID")
    .Or(Data.Group.Columns.OwnerPersonID).IsEqualTo("SomeContextID")
    .AndExpression(Data.Group.Columns.IsCallList).IsEqualTo(true)
    .CheckLogicalDelete().ToString();

我收到了这个查询(格式化我的):

SELECT <All columns>

 FROM [dbo].[tblGroups]
 WHERE [dbo].[tblGroups].[GroupID] <> @GroupID0
 AND ( -- first [AndExpression]
   [dbo].[tblGroups].[OwnerPersonID] = @OwnerPersonID1 --Data.Group.Columns.OwnerPersonID).IsEqualTo("someownerID")
   OR [dbo].[tblGroups].[OwnerPersonID] = @OwnerPersonID2 --.Or(Data.Group.Columns.OwnerPersonID).IsEqualTo("SomeContextID")
 ) -- close for first [AndExpression]
 AND ( -- second [AndExpression]
    [dbo].[tblGroups].[IsCallList] = @IsCallList4
 ) -- close for second [AndExpression]
 AND ([dbo].[tblGroups].[IsDeleted] IS NULL OR [dbo].[tblGroups].[IsDeleted] = 0)

如您所见,第一个 AndExpression 在其括号内包含 .Or(Data.Group.Columns.OwnerPersonID).IsEqualTo("SomeContextID"),这意味着 ..Expression 继续在括号内包含前面的语句,直到找到另一个 ..Expression(我们可以在第二个 AndExpression.

上观察到

在第一个 AndExpression 之后添加额外的 And/Or 方法加强了

的证明

Using ..Expression's without CloseExpression will encapsulate preceding statements in parentheses until another ..Expression is called.