我使用' PostgreSql'在.NET中使用实体框架(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...
我检查EF发送给PostgreSQL的SQL查询:
INSERT INTO "public"."MyClass"("Name") VALUES ("Test");
SELECT currval(pg_get_serial_sequence('"public"."MyClass"', 'Id')) AS "Id"
第一个看起来不错。如果我执行它,则在DB中创建新行(使用新生成的id) 第二个返回NULL,列的名称是' Id bigint'。 看来,此功能仅适用于数字ID。
是否可以使其适用于自动生成的“uuid”列?类型?
答案 0 :(得分:1)
您没有写下您使用的EF提供商。我认为它是npgsql。
根据最新消息来源,它应该返回Sql Erwin Brandstetter发布:
INSERT INTO public."MyClass"("Name") VALUES ("Test") RETURNING "Id";
以下是sql生成器的相关部分: SqlInsertGenerator class和 AppendReturning method
我会尝试最新版本的npgsql(甚至可以自己从源代码构建它)。
答案 1 :(得分:0)
使用RETURNING
子句简化:
INSERT INTO public."MyClass"("Name") VALUES ("Test") RETURNING "Id";
没有单独的SELECT
,因此不会混淆与SELECT
中的函数匹配的列的默认值。更简单,更快速,更清洁。
答案 2 :(得分:0)
我假设你正在使用https://github.com/npgsql/Npgsql
我想知道您使用的是什么版本,因为您可能正在使用源代码构建自己的dll,因为https://github.com/npgsql/Npgsql/pull/91还不是任何版本的一部分......如果您选择了PR91,那么您可能应该这样做樱花挑选这个PR160 https://github.com/npgsql/Npgsql/pull/160可以解决你的问题。