使用Entity Framework Core自动增加部分主键

Mar*_*tin 39 c# asp.net postgresql entity-framework entity-framework-core

我使用EF Core fluent API声明了以下模型:

modelBuilder.Entity<Foo>()
    .HasKey(p => new { p.Name, p.Id });
Run Code Online (Sandbox Code Playgroud)

当我在PostgreSQL中创建数据库时,这两个字段都被标记为主键,但Id字段未标记为自动增量.我也尝试过添加

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
Run Code Online (Sandbox Code Playgroud)

到Foo下的Id字段,没有它对迁移代码产生任何影响.有没有办法制作Id AI虽然它是PPK?

oct*_*ccl 48

那些数据注释应该可以解决问题,也许是与PostgreSQL提供程序相关的东西.

EF Core文档:

根据所使用的数据库提供程序,可以通过EF或数据库在客户端生成值.如果该值由数据库生成,则在将实体添加到上下文时,EF可以分配临时值.然后,此临时值将由数据库生成的值替换SaveChanges.

您也可以尝试使用此Fluent Api配置:

modelBuilder.Entity<Foo>()
            .Property(f => f.Id)
            .ValueGeneratedOnAdd();
Run Code Online (Sandbox Code Playgroud)

但正如我之前所说,我认为这与数据库提供商有关.尝试向数据库添加新行,稍后检查是否为Id列生成了值.

  • 只是后续操作,对于PostgreSQL,您不能将现有字段修改为AI。这导致了我之前遇到的异常,因此我不得不丢弃我的数据库,创建一个新的数据库并放入所有数据。 (2认同)

Mas*_*uso 12

首先,您不应该将Fluent Api与数据注释合并,因此我建议您使用以下其中一项:

确保你有关键设置

modelBuilder.Entity<Foo>()
            .HasKey(p => new { p.Name, p.Id });
modelBuilder.Entity<Foo>().Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Run Code Online (Sandbox Code Playgroud)

或者您也可以使用数据注释来实现它

public class Foo
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key, Column(Order = 0)]
    public int Id { get; set; }

    [Key, Column(Order = 1)]
    public string Name{ get; set; }
}
Run Code Online (Sandbox Code Playgroud)

  • HasDatabaseGeneratedOption似乎不存在于我正在使用的版本(7.0.0-rc1-final)中,或者我是否缺少扩展名或其他内容? (11认同)
  • 我试图坚持使用流畅的API,但据我所知,HasDatabaseGeneratedOption仅存在于EF6而不是EF7.或者是否需要使用扩展来访问该功能? (4认同)
  • 我不认为这解决了OP的问题.他正在将Fluent Api(他建立Ids命令)与Data Annotations合并(其中他指定`Id`属性是Identity).我个人不喜欢合并这两个功能,但他的配置应该有效.我认为正在发生的事情更多地取决于数据库提供商. (2认同)

Sai*_*sad 9

对于遇到此问题的任何人,即使在int主键上添加以下注释后仍然使用SQL Server数据库并仍然抛出异常

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
Run Code Online (Sandbox Code Playgroud)

请检查您的SQL,确保您的主键旁边有'IDENTITY(startValue,increment)',

CREATE TABLE [dbo].[User]
(
    [Id] INT IDENTITY(1,1) NOT NULL PRIMARY KEY
)
Run Code Online (Sandbox Code Playgroud)

这将使数据库在每次添加新行时递增id,起始值为1,增量为1.

我不小心忽略了我的SQL,这花了我一个小时的生命,所以希望这有助于某人!


小智 5

如下注释属性

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
Run Code Online (Sandbox Code Playgroud)

要将标识列用于新模型上所有值生成的属性,只需将以下内容放在上下文的OnModelCreating()中:

builder.ForNpgsqlUseIdentityColumns();
Run Code Online (Sandbox Code Playgroud)

这将创建使所有具有.ValueGeneratedOnAdd()的键和其他属性在默认情况下具有标识。您可以使用ForNpgsqlUseIdentityAlwaysColumns()始终拥有身份,也可以使用UseNpgsqlIdentityColumn()和UseNpgsqlIdentityAlwaysColumn()逐个属性地指定身份。

Postgres efcore价值创造

  • 在最新版本的 .netcore EF 下,ForNpgsqlUseIdentityColumns 已弃用,请使用以下行 builder.UseIdentityColumns (2认同)