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 следующее значение последовательностей?

Другие вопросы по тегам