обновление linq2db с помощью CTE в MySQL 8

#mysql #common-table-expression #linq2db

#mysql #common-table-expression #linq2db

Вопрос:

Этот вопрос касается linq2db.MySQL 3.1.5 и MySQL 8.0.21

Я получаю сообщение «У вас ошибка в вашем синтаксисе SQL …» при попытке запустить обновление (помечая повторяющиеся электронные письма) с использованием CTE в MySQL, как указано ниже

                 var cte = (
                        from x in db.GetTable<PEmailCleanupJobItem>()
                        group x by x.EmailAddress into eGroup
                        where eGroup.Count() > 1
                        select new { EmailAddress = eGroup.Key }
                ).AsCte();

                var qry = (
                    from e in db.GetTable<PEmailCleanupJobItem>()
                    from d in cte
                        .InnerJoin(d => e.EmailAddress == d.EmailAddress)
                    select e
                );

                await qry
                    .Set(e => e.IsDuplicate, true)
                    .UpdateAsync();
  

Это генерирует и отправляет в MySQL следующее

 --  MySql.Official MySql (asynchronously)
DECLARE @IsDuplicate UByte -- Boolean
SET     @IsDuplicate = 1

UPDATE `CTE_1` (`EmailAddress`)
AS
(
        SELECT
                `t1`.`email_address`
        FROM
                `emails` `t1`
        GROUP BY
                `t1`.`email_address`
        HAVING
                Count(*) > 1
)
FROM
        `emails` `d`
                INNER JOIN `CTE_1` `e` ON (`d`.`email_address` IS NULL AND `e`.`EmailAddress` IS NULL OR `d`.`email_address` = `e`.`EmailAddress`)
SET
        `d`.`is_duplicate` = @IsDuplicate
  

Обратите внимание, как UPDATE `CTE_1` (`EmailAddress`) генерируется вместо WITH `CTE_1` (`EmailAddress`)

Я бы вручную написал этот запрос (который работает) как

 WITH `CTE_1` (`EmailAddress`)
AS
(
        SELECT
                `t1`.`email_address`
        FROM
                `emails` `t1`
        GROUP BY
                `t1`.`email_address`
        HAVING
                Count(*) > 1
)
UPDATE 
    `emails` `d`
            INNER JOIN `CTE_1` `e` ON (`d`.`email_address` IS NULL AND `e`.`EmailAddress` IS NULL OR `d`.`email_address` = `e`.`EmailAddress`)
SET
    `d`.`is_duplicate` = 1
  

Это ошибка с linq2db или я что-то упускаю?

Комментарии:

1. Это ошибка. Пожалуйста, создайте проблему в репозитории linq2db GitHub. Я знаю, что обновление с помощью CTE тестируется только на Sql Server.

2. Спасибо Святослав, сделаю. Тот же cte отлично работает для SELECT и генерирует оператор в правильном порядке.

3. Исправлено в linq2db 3.1.6