Postgree INSERT ON CONFLICT DO NOTHING
От: swimmers  
Дата: 21.05.21 17:27
Оценка:
Здравствуйте,

Что-то не пойму, какой нужно написать код, что-бы при вставке при совпадении ПК ничего не вставлялось и не возникала ошибка?
Т.е. что-бы получился SQL вида INSERT ... ON CONFLICT (...) DO NOTHING?

db.Table.InsertOrUpdate(insertExpr, updateExpr, keySelector)?
Но что писать во втором параметре (updateExpr)?

Или есть какой-то другой рекомендуемый способ?
Re: Postgree INSERT ON CONFLICT DO NOTHING
От: Mace Windu  
Дата: 22.05.21 08:21
Оценка:
Здравствуйте, swimmers, Вы писали:

S>Здравствуйте,


S>Что-то не пойму, какой нужно написать код, что-бы при вставке при совпадении ПК ничего не вставлялось и не возникала ошибка?

S>Т.е. что-бы получился SQL вида INSERT ... ON CONFLICT (...) DO NOTHING?

S>db.Table.InsertOrUpdate(insertExpr, updateExpr, keySelector)?

S>Но что писать во втором параметре (updateExpr)?

S>Или есть какой-то другой рекомендуемый способ?


Полноценная поддержка ON CONFLICT и подобных пока только в планах. Нужно время либо добровольцы.

InsertOrUpdate для postgresql генерирует INSERT ON CONFLICT UPDATE. Если устраивает такое, то в update просто указать обновление поля на себя же например
db.Table.InsertOrUpdate(
  // данные для insert: PK поля + остальные поля которые надо вставить
  () => new Table() {pk=pk_value, field1=value1, field2=value2},
  // данные для update: обновить field1 значением этого же поля
  record => new Table() { field1 = record.field1 });

как-то так
Re[2]: Postgree INSERT ON CONFLICT DO NOTHING
От: swimmers  
Дата: 22.05.21 08:46
Оценка:
Здравствуйте, Mace Windu, Вы писали:

MW>Полноценная поддержка ON CONFLICT и подобных пока только в планах. Нужно время либо добровольцы.


А вот в PostgreSQLSqlBuilder.BuildInsertOrUpdateQuery вроде все уже написано, но что и как написать, что-бы попасть сюда?

if (insertOrUpdate.Update.Items.Count > 0)
    {
        base.StringBuilder.AppendLine(") DO UPDATE SET");
        base.Indent++;
        bool flag2 = true;
        foreach (SqlSetExpression item in insertOrUpdate.Update.Items)
        {
            if (!flag2)
            {
                base.StringBuilder.AppendLine(this.Comma);
            }
            flag2 = false;
            base.AppendIndent();
            base.BuildExpression(item.Column, false, true, true);
            base.StringBuilder.Append(" = ");
            base.BuildExpression(item.Expression, true, true, true);
        }
        base.Indent--;
        base.StringBuilder.AppendLine();
    }
    else
    {
        base.StringBuilder.AppendLine(") DO NOTHING");
    }
Отредактировано 22.05.2021 8:46 swimmers . Предыдущая версия .
Re[3]: Postgree INSERT ON CONFLICT DO NOTHING
От: Mace Windu  
Дата: 22.05.21 09:15
Оценка:
Здравствуйте, swimmers, Вы писали:

S>Здравствуйте, Mace Windu, Вы писали:


MW>>Полноценная поддержка ON CONFLICT и подобных пока только в планах. Нужно время либо добровольцы.


S>А вот в PostgreSQLSqlBuilder.BuildInsertOrUpdateQuery вроде все уже написано, но что и как написать, что-бы попасть сюда?


хм, точно. тогда пустой update вторым параметром если пропустит такое:
record => new Table()
Re[4]: Postgree INSERT ON CONFLICT DO NOTHING
От: swimmers  
Дата: 22.05.21 09:46
Оценка:
Здравствуйте, Mace Windu, Вы писали:

MW>хм, точно. тогда пустой update вторым параметром если пропустит такое:

MW>
MW>record => new Table()
MW>


Падает с ошибкой "new Table() не может быть сконвертирован в SQL"
Re[5]: Postgree INSERT ON CONFLICT DO NOTHING
От: Mace Windu  
Дата: 22.05.21 09:54
Оценка:
Здравствуйте, swimmers, Вы писали:

S>Падает с ошибкой "new Table() не может быть сконвертирован в SQL"


Ну это баг по хорошему. Мы ожидаем init expression тут. Вот рабочий пример https://github.com/linq2db/linq2db/blob/efaa567829d35a7eed1c03b8d749f0ca0535062a/Tests/Linq/Update/InsertTests.cs#L1102
Т.е. надо так
record => new Table() {}
Re[6]: Postgree INSERT ON CONFLICT DO NOTHING
От: swimmers  
Дата: 23.05.21 13:35
Оценка:
Здравствуйте, Mace Windu, Вы писали:

MW>Т.е. надо так

MW>
MW>record => new Table() {}
MW>


Действительно, фунциклирует!
Благодарю за подсказку!

Но, по хорошему, вариант без инициализатора тоже должен работать.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.