【问题标题】:What happens if I use `AndExpression` without `CloseExpression`如果我在没有 `CloseExpression` 的情况下使用 `AndExpression` 会发生什么
【发布时间】:2017-10-19 15:38:27
【问题描述】:

我有这个亚音速查询:

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 将前面的语句括在括号内。

上面的亚音速查询如何翻译成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..Expressions 是如何处理的?

【问题讨论】:

    标签: c# subsonic


    【解决方案1】:

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

    【讨论】:

    • 这并不能直接回答我的问题。 +1 虽然因为你指出了正确的方向来得到我的答案
    【解决方案2】:

    正如@MikeWalsh 在他的answer 中所指出的,调用.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)
    

    这告诉我们,在没有CloseExpression 的情况下调用AndExpression/OrExpression,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 方法可以加强证明

    使用不带CloseExpression..Expression 会将前面的语句封装在括号中,直到调用另一个..Expression

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-19
      相关资源
      最近更新 更多