Как избежать дублирования ключей в Entity Framework

У меня есть очень простой класс, созданный Entity Framework (V 6.2) со свойством, которое также является первичным ключом.

public class Product
{
    public string Name { get; set; }
}

Как я могу убедиться, что когда я создаю новый элемент (или изменяю один из существующих), это не позволяет мне сделать это, если имя уже существует?

Я знаю, что MyContext.SaveChanges() сгенерирует исключение, но можно ли сделать это раньше? Как при звонке в MyContext.Products.Add(MyNewProduct)? Или когда имя изменено?

Я мог бы изменить свойство set в автоматически сгенерированном файле, созданном EF, но оно будет стираться каждый раз, когда я регенерирую модель ...

Используете ли вы подход CodeFirst или DatabaseFirst?

Wurd 13.09.2018 16:15

База данных @Wurd сначала, иначе ему не пришлось бы регенерировать модель

i regular 13.09.2018 16:15

Просто имейте в виду, что если вы генерируете ключ в коде (не db auto int) и ваше приложение имеет много одновременных запросов, вы можете столкнуться с проблемами параллелизма. Например, запрос A => B => A получает ID => B получает ID => A Saved => B конфликт параллелизма с A при сохранении.

Wurd 13.09.2018 16:24

@Wurd Я использую подход Database First. Я не буду сталкиваться с проблемами параллелизма, так как эта программа предназначена для одновременного использования только на одном компьютере (я буду помнить об этом, если это изменится).

Martin Verjans 14.09.2018 08:06
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
4
490
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий
        if (db.Products.Any(p => p.Name == newProduct.Name))
        {
            return "A record with the same name already exists.";
        }
        else
        {
            db.Products.Add(newProduct);
            db.SaveChanges();
        }

Я согласен, это ваш лучший вариант. Преимущество использования any заключается в том, что он возвращается сразу после того, как находит совпадение.

i regular 13.09.2018 16:14

Прежде всего, я не думаю, что проверка уникальности в установщике или в методе context.Add () - хорошая идея, поскольку вы можете столкнуться с проблемами производительности при одновременном добавлении нескольких сущностей. Возможно, лучше добавить проверку в переопределенном методе SaveChanges ().

Вы можете изменить шаблон генерации кода EF (https://docs.microsoft.com/en-us/ef/ef6/modeling/designer/codegen/), чтобы генерировать проверки для каждого требуемого типа сущности на основе некоторого расширенная собственность или некоторых других метаданных в базе данных, примерно так:

public override int SaveChanges()
{
    var productNames = ChangeTracker.Entries<Products>()
        .Where(x => (x.State == EntityState.Added) || 
            (x.State == EntityState.Modified && x.OriginalValues["Name"] != x.CurrentValues["Name"]))
        .Select(x => x.Entity.Name)
        .ToList();
    if (Products.Any(x => productNames.Contains(x.Name)))
    {
        throw new Exception("Duplicated keys");
    }
    // same goes for other similar entities

    return base.SaveChanges();
}

Я проверил вашу ссылку, но они, видимо, пытаются отговорить от изменения шаблонов. Спасибо, в любом случае

Martin Verjans 14.09.2018 16:57

Я не думаю, что они препятствуют изменению шаблонов в целом. Насколько я понимаю, они просто рекомендуют использовать одни шаблоны в качестве основы для изменений по сравнению с другими.

Sam Arustamyan 14.09.2018 17:46

Другие вопросы по теме