Сложная проблема с postgres, возвращающим id или выберите currval (pg_get_serial_sequence ('<table>', '<id>'))? - PullRequest
0 голосов
/ 05 января 2019

Я пытаюсь использовать Dapper, Npgsql для подключения к базе данных postgres из приложения .net. После вставки я хочу знать идентификатор вставленной строки. Я прочитал и попробовал варианты , обсуждаемые здесь . Я пытался использовать returning id так:

id = connection.Execute("insert into document_tag (tag) values (@tag) returning id;",
            new { tag },
            transaction);

но я получаю только '1' в идентификаторе.

Я также пытался использовать currval так:

id = connection.Execute("insert into document_tag (tag) values (@tag); select currval(pg_get_serial_sequence('document_tag','id'));",
            new { tag },
            transaction);

Даже в этом случае я получаю только '1' в id.

В обоих случаях вставка прошла успешно, и столбец id в базе данных имел действительный серийный номер, отличный от «1».

Мои ожидания неверны или есть альтернатива?

Ответы [ 2 ]

0 голосов
/ 05 января 2019

Как предложено @Shay: используйте connection.QueryFirst<int> вместо connection.Exeucte и все заработало. Обновлен рабочий код:

id = connection.QueryFirst<int>("insert into document_tag (tag) values (@tag) returning id;",
        new { tag },
        transaction);
0 голосов
/ 05 января 2019

Чтобы вставить строку и получить столбец, сгенерированный базой данных, используйте:

INSERT INTO document_tag (tag) VALUES (@tag) RETURNING id

Обратите внимание, что перед "RETURNING" нет точки с запятой - это просто предложение оператора INSERT, , как вы можете видеть в документации PostgreSQL .

Кроме того, после добавления предложения RETURNING оператор INSERT возвращает набор результатов, содержащий запрошенную информацию, так же, как если бы вы выполнили оператор SELECT. Dapper's Execute() предназначен для выполнения без результирующих наборов, поэтому вам нужно будет переключиться на Query() и, возможно, добавить метод Single(), чтобы извлечь единственное необходимое вам значение. Альтернативой будет ExecuteScalar().

...