Postgresql: автоматическое создание 'uuid' не работает с EntityFramework
Я работаю с 'PostgreSql' в.NET, используя Entity Framework (подход POCO).
Моя цель - создать новую запись в базе данных, генерирующую Id (uuid) на стороне базы данных, и извлечь сгенерированный Id на сервер (такой сценарий отлично работает с SQL Server).
Моя модель выглядит так:
public class MyClass
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public string Name { get; set; }
}
В столбце PostgreSql 'Id' имеет значение по умолчанию 'uuid_generate_v4()'
Когда я пытаюсь добавить новый объект в БД с помощью EF, я получаю следующую ошибку:
A null store-generated value was returned for a non-nullable member 'Id' of type...
Я проверяю SQL-запросы, которые EF отправляет в PostgreSQL:
INSERT INTO "public"."MyClass"("Name") VALUES ("Test");
SELECT currval(pg_get_serial_sequence('"public"."MyClass"', 'Id')) AS "Id"
Первый выглядит хорошо. Если я выполню его, новая строка будет создана в БД (с новым сгенерированным идентификатором). Вторая возвращает NULL, а имя столбца - "Id bigint". Кажется, что эта функция работает только для числовых идентификаторов.
Можно ли заставить его работать для автоматически сгенерированного столбца типа 'uuid'?
3 ответа
Вы не написали, каким провайдером EF вы пользуетесь. Я полагаю, это npgsql.
Согласно последним источникам, он должен вернуть Sql Erwin Brandstetter:
INSERT INTO public."MyClass"("Name") VALUES ("Test") RETURNING "Id";
Вот соответствующие части генераторов sql: класс SqlInsertGenerator и метод AppendReturning
Я бы попробовал последнюю версию npgsql (возможно, даже собрал ее сам из исходного кода).
Я предполагаю, что вы используете https://github.com/npgsql/Npgsql
Мне интересно, какую версию вы используете, потому что вы, вероятно, создаете свою собственную dll из исходного кода, поскольку https://github.com/npgsql/Npgsql/pull/91 еще не является частью какого-либо релиза... Если вы cherry- выбрал PR91, вы, вероятно, должны выбрать также этот PR160 https://github.com/npgsql/Npgsql/pull/160 который решает именно вашу проблему.
Упростить с RETURNING
пункт:
INSERT INTO public."MyClass"("Name") VALUES ("Test") RETURNING "Id";
Нет отдельного SELECT
, поэтому нет путаницы в отношении значения по умолчанию для столбца, соответствующего функции в вашем SELECT
, Проще, быстрее, чище.
Больше деталей:
PostgreSQL следующее значение последовательностей?