Subsonic 2.2 SqlQuery 与内连接和Where

发布于 2024-09-13 20:55:41 字数 1644 浏览 1 评论 0原文

我正在尝试使用 SqlQuery 功能将以下 SQL 转换为 Subsonic 语法:

SELECT DISTINCT * FROM FamilyMemberTeamRole FMTR 
INNER JOIN TeamRole TR ON FMTR.TeamRoleId = TR.TeamRoleId
INNER JOIN Team T ON T.TeamId = TR.TeamId
LEFT JOIN FamilyMemberClassHistory FMCH ON FMCH.FamilyMemberClassHistoryId = FMTR.FamilyMemberClassHistoryId
LEFT JOIN CBSClass CG ON CG.CBSClassGroupId = FMCH.CBSClassGroupId
LEFT JOIN CBSClassSession CS ON CG.CBSClassGroupId = CS.CBSClassGroupId 
AND (CS.ClassStartDate <= FMTR.EndDate or FMTR.EndDate IS NULL)
AND (CS.IsHistory = 0 OR CS.IsHistory = NULL)
WHERE FMTR.FamilyMemberId = @FamilyMemberId

我想出了这个,但是最后一个左连接的语法有问题,因为我不知道如何将 SqlQuery 中的值与其自身进行比较。

SqlQuery sql = new Select().From(FamilyMemberTeamRole.Schema.TableName)
.InnerJoin(TeamRole.TeamRoleIdColumn, FamilyMemberTeamRole.TeamRoleIdColumn)
.InnerJoin(Team.TeamIdColumn, TeamRole.TeamIdColumn)
.LeftOuterJoin(FamilyMemberClassHistory.FamilyMemberClassHistoryIdColumn, FamilyMemberTeamRole.FamilyMemberClassHistoryIdColumn)
.LeftOuterJoin(CBSClass.CBSClassGroupIdColumn, FamilyMemberClassHistory.CBSClassGroupIdColumn)
.LeftOuterJoin(CBSClassSession.CBSClassGroupIdColumn, CBSClass.CBSClassGroupIdColumn)
.AndExpression(CBSClassSession.Columns.ClassStartDate).IsLessThanOrEqualTo(FamilyMemberTeamRole.Columns.EndDate)
.Or(FamilyMemberTeamRole.Columns.EndDate).IsNull().CloseExpression()
.AndExpression(CBSClassSession.Columns.IsHistory).IsEqualTo(false)
.Or(CBSClassSession.Columns.IsHistory).IsNull().CloseExpression()
.Where(FamilyMemberTeamRole.Columns.FamilyMemberId).IsEqualTo(this.FamilyMemberId)
.Distinct();

I am trying to convert the following SQL into Subsonic syntax using the SqlQuery functionality:

SELECT DISTINCT * FROM FamilyMemberTeamRole FMTR 
INNER JOIN TeamRole TR ON FMTR.TeamRoleId = TR.TeamRoleId
INNER JOIN Team T ON T.TeamId = TR.TeamId
LEFT JOIN FamilyMemberClassHistory FMCH ON FMCH.FamilyMemberClassHistoryId = FMTR.FamilyMemberClassHistoryId
LEFT JOIN CBSClass CG ON CG.CBSClassGroupId = FMCH.CBSClassGroupId
LEFT JOIN CBSClassSession CS ON CG.CBSClassGroupId = CS.CBSClassGroupId 
AND (CS.ClassStartDate <= FMTR.EndDate or FMTR.EndDate IS NULL)
AND (CS.IsHistory = 0 OR CS.IsHistory = NULL)
WHERE FMTR.FamilyMemberId = @FamilyMemberId

I came up with this however something is wrong with my syntax on the last left join as I do not know how to compare values from within the SqlQuery to themselves.

SqlQuery sql = new Select().From(FamilyMemberTeamRole.Schema.TableName)
.InnerJoin(TeamRole.TeamRoleIdColumn, FamilyMemberTeamRole.TeamRoleIdColumn)
.InnerJoin(Team.TeamIdColumn, TeamRole.TeamIdColumn)
.LeftOuterJoin(FamilyMemberClassHistory.FamilyMemberClassHistoryIdColumn, FamilyMemberTeamRole.FamilyMemberClassHistoryIdColumn)
.LeftOuterJoin(CBSClass.CBSClassGroupIdColumn, FamilyMemberClassHistory.CBSClassGroupIdColumn)
.LeftOuterJoin(CBSClassSession.CBSClassGroupIdColumn, CBSClass.CBSClassGroupIdColumn)
.AndExpression(CBSClassSession.Columns.ClassStartDate).IsLessThanOrEqualTo(FamilyMemberTeamRole.Columns.EndDate)
.Or(FamilyMemberTeamRole.Columns.EndDate).IsNull().CloseExpression()
.AndExpression(CBSClassSession.Columns.IsHistory).IsEqualTo(false)
.Or(CBSClassSession.Columns.IsHistory).IsNull().CloseExpression()
.Where(FamilyMemberTeamRole.Columns.FamilyMemberId).IsEqualTo(this.FamilyMemberId)
.Distinct();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

橘亓 2024-09-20 20:55:41

您始终可以使用 BuildSqlStatement() 方法检查 subsonic 为您生成的查询:

SqlQuery query = DB.Select().From<Product>();
String output = query.BuildSqlStatemtent();

但我想我知道问题是什么:据我所知,SubSonic2 Join 方法不支持连接多个列: subsonic 2 连接多列

所以你基本上有两个选择。

a)做一个“逗号连接”

SELECT * FROM table1
INNER JOIN table2 ON table1.id = table2.table1_id

与下面的查询相同,但更具可读性

SELECT * FROM table1, table2
WHERE table1.id = table2.table1_id

至少对于mysql来说是这样

编辑:正如我在问题中发现的那样,这不适用于亚音速(但已经忘记了)

http://www.mysqlperformanceblog。 com/2010/04/14/is-there-a-performance-difference- Between-join-and-where/

b) 使用 Subsonic 后门 InlineQuery 来执行普通 sql。

    private class Process
    {
        public Int64 Id { get; set; }
        public string User { get; set; }
        public string Host { get; set; }
        public string Db { get; set; }
        public string Command { get; set; }
        public string State { get; set; }
        public string Info { get; set; }
    }

    var result = DB.Query().ExecuteTypedList<Process>("SHOW FULL PROCESSLIST");

You can always check what query subsonic generates for you with the BuildSqlStatement() method:

SqlQuery query = DB.Select().From<Product>();
String output = query.BuildSqlStatemtent();

But I think I know what the problem is: SubSonic2 Join methods don't support joining on multiple columns as far as I know: subsonic 2 join on multiple columns

So you basically you have two options.

a) do a "comma join"

SELECT * FROM table1
INNER JOIN table2 ON table1.id = table2.table1_id

is the same as this query below but more readable

SELECT * FROM table1, table2
WHERE table1.id = table2.table1_id

At least that's true for mysql

Edit: That won't work with subsonic as I figured out in my question (but have forgetten)

http://www.mysqlperformanceblog.com/2010/04/14/is-there-a-performance-difference-between-join-and-where/

b) Use an InlineQuery which is subsonic's backdoor to execute plain sql.

    private class Process
    {
        public Int64 Id { get; set; }
        public string User { get; set; }
        public string Host { get; set; }
        public string Db { get; set; }
        public string Command { get; set; }
        public string State { get; set; }
        public string Info { get; set; }
    }

    var result = DB.Query().ExecuteTypedList<Process>("SHOW FULL PROCESSLIST");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文