Проблема при вставке двух последовательных строк в базу данных - PullRequest
0 голосов
/ 04 февраля 2020

У меня есть эта функция, и она отлично работает

       public  DemandeConge Creat(DemandeConge DemandeConge)
    {

        try
        {
            var _db = Context;
            int numero = 0;
            //??CompanyStatique
            var session = _httpContextAccessor.HttpContext.User.Claims.ToList();
            int currentCompanyId = int.Parse(session[2].Value);

            numero = _db.DemandeConge.AsEnumerable()
                          .Where(t => t.companyID == currentCompanyId)
                          .Select(p => Convert.ToInt32(p.NumeroDemande))
                          .DefaultIfEmpty(0)
                          .Max();
            numero++;
            DemandeConge.NumeroDemande = numero.ToString();
            //_db.Entry(DemandeConge).State = EntityState.Added;
            _db.DemandeConge.Add(DemandeConge);
            _db.SaveChanges();

            return DemandeConge;
        }
        catch (Exception e)
        {
            return null;
        }
    }

Но только когда я пытаюсь вставить другой запрос на отпуск сразу после его вставки (без ожидания или обновления страницы) Появляется ошибка, сообщающая, что этот новый demand.id существует

Я думаю, что мне нужно добавить refre sh после сохранения изменений? Любая помощь и спасибо

1 Ответ

2 голосов
/ 05 февраля 2020

Код такой:

        numero = _db.DemandeConge.AsEnumerable()
                      .Where(t => t.companyID == currentCompanyId)
                      .Select(p => Convert.ToInt32(p.NumeroDemande))
                      .DefaultIfEmpty(0)
                      .Max();
        numero++;

Очень плохой шаблон. Вы должны оставить генерацию вашего "Numberro" (ID) до базы данных через столбец Identity. Установите это в своей БД (если БД сначала) и настройте отображение для этого столбца как DatabaseGenerated.Identity.

Однако ваш код вызывает много вопросов .. Почему это строка вместо Int? Это будет ошибка для использования столбца идентификаторов.

Причина, по которой вы захотите избежать такого кода, заключается в том, что каждый запрос будет запрашивать базу данных, чтобы получить «максимальный» идентификатор, как только вы получите два запроса, выполняющиеся относительно одновременно, вы получите 2 запроса, которые говорят, что максимальный ID равен «100», прежде чем любой из них сможет зарезервировать и вставить 101, поэтому оба пытаются вставить 101. Используя столбцы Identity, база данных получит 2x вставки и сначала даст им идентификатор. -Давай-первым обслужен. EF может автоматически управлять связанными FK вокруг этих новых идентификаторов, когда вы настраиваете свойства навигации для отношений. (Вместо того, чтобы пытаться устанавливать FK вручную, что является типичной причиной для разработчиков, пытающихся получить новый идентификатор приложения на стороне приложения)

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

const int MAXRETRIES = 5;

var session = _httpContextAccessor.HttpContext.User.Claims.ToList();
int currentCompanyId = int.Parse(session[2].Value);
int insertAttemptCount = 0;

while(insertAttempt < MAXRETRIES)
{
    try
    {
        numero = Context.DemandeConge
            .Where(t => t.companyID == currentCompanyId)
            .Select(p => Convert.ToInt32(p.NumeroDemande))
            .DefaultIfEmpty(0)
            .Max() + 1;
        DemandeConge.NumeroDemande = numero.ToString();
        Context.DemandeConge.Add(DemandeConge);
        Context.SaveChanges();
        break;
    }
    catch (UpdateException)
    {
        insertAttemptCount++;
        if (insertAttemptCount >= MAXRETRIES)
            throw; // Could not insert, throw and handle exception rather than return #null.
    }
}
return DemandeConge;

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...