Уникальный первичный ключ с использованием Entity Framework

2

Я новичок в EF. Допустим, у меня есть таблица в БД, например:

ID    FirstName     LastName    DateOfBirth
-------------------------------------------
1     John          Smith       1.1.1990
2     Mary          Wilson      5.1.1991

Теперь я вставляю новую сущность в таблицу, используя EF:

dbcontext.Persons.Add(new Person
{
    FirstName = "John",
    LastName = "Smith",
    DateOfBith = "1.1.1990"
});
dbcontext.SaveChanges();

Мне нужен код, чтобы вызвать исключение, потому что эта строка уже существует в базе данных, но EF делает то, что она увеличивает столбец ID на 1 и создает новую запись:

ID    FirstName     LastName    DateOfBirth
--------------------------------------------
1     John          Smith       1.1.1990
2     Mary          Wilson      5.1.1991
3     John          Smith       1.1.1990

EF даже способен на это?

  • 0
    docs.microsoft.com/en-us/ef/core/modeling/keys
  • 0
    Применить уникальное ограничение stackoverflow.com/a/41257827/2630817
Показать ещё 2 комментария
Теги:
entity-framework

2 ответа

4
Лучший ответ

Вы уже определили свой столбец ID как столбец идентификаторов, и он считается вашим первичным ключом и будет увеличиваться на единицу при каждом добавлении новой записи в таблицу. Вот почему вам разрешено вставлять повторяющиеся объекты. Вам нужно указать, какой столбец нужно объявить как PK, либо в вашей модели, если вы используете подход с первым кодом и с помощью аннотации данных, что-то вроде этого:

[Key]
public string FirstName { get; set; }

Или с помощью уникального ограничения:

[Index("IX_UniqueConstraint", 1, IsUnique = true)]
public string FirstName { get; set; }

[Index("IX_UniqueConstraint", 2, IsUnique = true)]
public string LastName { get; set; }

[Index("IX_UniqueConstraint", 3, IsUnique = true)]
public DateTime DateOfBirth { get; set; }

Вы также можете использовать свободный API для этой цели:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Persons>().HasKey(c => new { c.FirstName, c.LastName, c.DateOfBirth });
}

Или, если вы используете подход, основанный на DB, вы можете объявить его в своей базе данных.

  • 0
    спасибо за быстрый ответ - при использовании второго решения я получаю это исключение: «Столбец« FirstName »в таблице« dbo.People »относится к типу, который недопустим для использования в качестве ключевого столбца в индексе.« Я не уверен, что не так - мой модельный класс - public int ID {get; установлен; } [Index ("IX_UniqueConstraint", 1, IsUnique = true)] public string FirstName {get; установлен; } [Index ("IX_UniqueConstraint", 2, IsUnique = true)] public string LastName {get; установлен; } [Index ("IX_UniqueConstraint", 3, IsUnique = true)] public DateTime BirthDate {get; установлен; }
  • 0
    @xcelm В SQL Server есть ограничение (до 2008 R2), что varchar (MAX) и nvarchar (MAX) (и некоторые другие типы, такие как text, ntext) не могут использоваться в индексах. У вас есть 2 варианта: проверить это сообщение stackoverflow.com/a/2864174/2946329
Показать ещё 6 комментариев
2

С EF вам нужно будет сделать что-то вроде этого:

[Index("IX_UniqueConstraint", 1, IsUnique = true)]
public string FirstName { get; set; }

[Index("IX_UniqueConstraint", 2, IsUnique = true)]
public string LastName { get; set; }

[Index("IX_UniqueConstraint", 3, IsUnique = true)]
public DateTime DateOfBirth { get; set; }

Это наложит уникальное ограничение на 3 столбца.

  • 0
    Привет в первую очередь спасибо за быстрый ответ. Ваше решение работает, хотя оно не работает так, как я ожидал - если я попытаюсь ввести First Name = "Joe" и LastName = "Smith", то я получаю нарушение ошибки PK. Мне нужно проверить, находится ли вся строка (конечно, только указанные столбцы) в БД, и если хотя бы один из них отличается, сохраните запись в БД. Любая идея, как справиться с этим?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню