Автоматическое увеличение частичного первичного ключа с помощью ядра 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 генерация стоимости
Ответ 5
Указание типа столбца как последовательного для PostgreSQL для генерации идентификатора.
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column(Order=1, TypeName="serial")]
public int ID { get; set; }
https://www.postgresql.org/docs/current/static/datatype-numeric.html#DATATYPE-SERIAL