Subsonic 2.2 SqlQuery с внутренним соединением и где - PullRequest
0 голосов
/ 10 августа 2010

Я пытаюсь преобразовать следующий SQL в Subsonic синтаксис с использованием функциональности SqlQuery:

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();

1 Ответ

1 голос
/ 13 августа 2010

Вы всегда можете проверить, какой запрос subsonic генерирует для вас, с помощью метода BuildSqlStatement():

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

Но я думаю, что знаю, в чем проблема: методы соединения SubSonic2 не поддерживают объединение нескольких столбцов, насколько мне известно: дозвуковое соединение 2 в нескольких столбцах

Таким образом, у вас есть два варианта.

а) сделать "запятую"

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) Использовать InlineQuery, который является бэкдором от subsonic, для выполнения простого 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");
...