Автоматическое увеличение частичного первичного ключа с помощью ядра Entity Framework

Я описал следующую модель с использованием API-интерфейса EF Core:

modelBuilder.Entity<Foo>()
    .HasKey(p => new { p.Name, p.Id });

Оба поля помечены как первичный ключ, когда я создаю базу данных в PostgreSQL, но поле Id не помечено как автоматическое приращение. Я также попытался добавить

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

в поле Id под Foo, не внося никакого изменения в код миграции. Есть ли способ сделать Id AI, хотя это PPK?

Ответ 1

Ну, эти аннотации данных должны делать трюк, возможно, что-то связано с Поставщиком PostgreSQL.

Из Документация EF Core:

В зависимости от используемого поставщика базы данных могут генерироваться значения клиентская сторона EF или в базе данных. Если значение генерируется базы данных, тогда EF может назначить временное значение при добавлении объекта к контексту. Это временное значение будет заменено на генерируемое базой данных во время SaveChanges.

Вы также можете попробовать эту конфигурацию Fluent Api:

modelBuilder.Entity<Foo>()
            .Property(f => f.Id)
            .ValueGeneratedOnAdd();

Но, как я сказал ранее, я думаю, что это связано с провайдером БД. Попробуйте добавить новую строку в свою БД и позже проверить, если было создано значение столбцу Id.

Ответ 2

Прежде всего, вы не должны объединять Fluent Api с аннотацией данных, поэтому я предлагаю вам использовать одно из следующих:

убедитесь, что у вас есть корреляция, установите клавиши

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

ИЛИ, вы можете достичь этого, используя аннотацию данных

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

    [Key, Column(Order = 1)]
    public string Name{ get; set; }
}

Ответ 3

Всем, кто сталкивался с этим вопросом, кто использует базу данных SQL Server и по-прежнему создает исключение даже после добавления следующей аннотации в первичный ключ int

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }

Пожалуйста, проверьте ваш SQL, убедитесь, что ваш первичный ключ имеет "IDENTITY (startValue, increment)" рядом с ним,

CREATE TABLE [dbo].[User]
(
    [Id] INT IDENTITY(1,1) NOT NULL PRIMARY KEY
)

Это приведет к тому, что база данных будет увеличивать идентификатор каждый раз, когда добавляется новая строка, с начальным значением 1 и шагом 1.

Я случайно упустил из виду, что в моем SQL это стоило мне часа моей жизни, так что, надеюсь, это кому-то поможет !!!

Ответ 4

Аннотируйте собственность как ниже

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }

Чтобы использовать столбцы идентификаторов для всех сгенерированных значений свойств в новой модели, просто поместите следующее в свой контекст OnModelCreating():

builder.ForNpgsqlUseIdentityColumns();

Это создаст все ключи и другие свойства, которые имеют .ValueGeneratedOnAdd() имеют Identity по умолчанию. Вы можете использовать ForNpgsqlUseIdentityAlwaysColumns(), чтобы всегда иметь Identity, и вы также можете указать идентичность для каждого свойства с помощью UseNpgsqlIdentityColumn() и UseNpgsqlIdentityAlwaysColumn().

postgres efcore генерация стоимости