Проблема автоматического приращения шаблона репозитория LINQ to SQL - PullRequest
1 голос
/ 05 мая 2011

У меня странная проблема, и я пытаюсь выяснить, был ли это мой код или что-то напутало с базой данных.У меня есть таблица WebClienteLogin, которая имеет атрибут Id (первичный ключ, автоинкремент).Я вставляю новую запись, когда пользователь регистрируется на сайте.

Вчера утром значение Id последнего зарегистрированного пользователя достигло около 9000, а днем ​​оно начало забавным образом прыгать, поэтому у следующего пользователя был Id 1200, 25000 ..... и он достиг 290000Однако сегодня оно продолжается как обычно (с увеличением на 1).Из статистики видно, что это происходит, когда одновременно регистрируется большое количество пользователей.

Используемые технологии: SQL Server 2008 R2, ASP.NET MVC2, .NET 3.5

Я использую шаблон репозитория с LINQ.Вот моя реализация одного из моих репозиториев.

public SQLWebClientLoginRepository(string connectionString)
{
                dataContext = new DataContext(connectionString);
                tabla = dataContext.GetTable<WebClientLogin>(); 
}


public bool Save(WebClientLogin user)
            {
                bool success = true;            

                try
                {
                    if (user.Id == 0)
                    {
                        tabla.InsertOnSubmit(user);
                    }
                    else if (tabla.GetOriginalEntityState(user) == null)
                    {
                        tabla.Attach(user);
                        tabla.Context.Refresh(RefreshMode.KeepCurrentValues, user);
                    }
                    tabla.Context.SubmitChanges();  
                }
                catch
                {
                    ......
                }

                return success;
     }

Кроме того, у пользователя есть другой объект, прикрепленный к нему, поэтому он выполняет INSERT в две таблицы, а LINQ упаковывает его в транзакцию.

  var user = new WebClientLogin();
  // assigning other properties
  user.WebClient = new WebClient { // setting propeties }

  webClientLoginRepository.Save(user)

InЖурнал я получаю исключение:

Была предпринята попытка удалить связь между WebClientLogin и WebCLient. Однако один из внешних ключей отношения (WebClient.WebCLientLogin_id) не может быть установлен равным нулю. "исключение

Понятия не имею, почему он это делает! Кто-нибудь испытывал что-то подобное?

Ответы [ 3 ]

0 голосов
/ 05 мая 2011

Я немного изменил репозиторий, но, похоже, он исправил эту проблему, но теперь у меня есть другая.

public bool Save(WebClientLogin login, WebClient client)
        {
            var created = false;

            using (var transaction = new TransactionScope())
            {
                try
                {
     // insert WebClientLogin first
                    tablalogin.InsertOnSubmit(login);
                    dataContext.SubmitChanges();

     // insert WebClient second
                    client.WebClientLogin_id = login.Id;
                    tablacliente.InsertOnSubmit(client);

                    dataContext.SubmitChanges();
                    created = true;
                    transaction.Complete();
                }
                catch (Exception ex)
                {
                    //
                }
            }
            return created;
        }

Когда большое количество пользователей, я вставляю только WebClientLogin, но не WebClient и я получаю это исключение:

Internal .Net Framework Data Provider error 60
0 голосов
/ 06 мая 2011

Ну ... все приложение выдавало множество других странных исключений.Итак, мы посетили нашего хозяина и обнаружили, что его вызвало.На хосте настроено 3 выделенных веб-сервера и 1 сервер базы данных.Они настроили балансировщик нагрузки и dfs для веб-серверов.Они отключили 2 из 3 серверов и провели стресс-тестирование.С тех пор не было ошибок / исключений или ошибочных транзакций.Похоже, проблема с сервером.

0 голосов
/ 05 мая 2011

Начальное состояние базы данных:

WebClientLogin
ID = 900

WebClient
ID = 1, WebClientLogin_Id = 900

В памяти до изменений:

WebClientLogin
ID = 900

WebClient
ID = 1, WebClientLogin_Id = 900, WebClientLogin = that instance with 900

Изучите свойство WebClient WebClientLogin. В памяти во время SubmitChanges:

WebClientLogin
ID = 900

WebClient (original instance)
ID = 1, WebClientLogin_Id = 900, WebClientLogin = null

WebClient  (new instance!)
ID = 0, WebClientLogin_Id = 900, WebClientLogin = that instance with 900

Попытки внесения изменений в базу данных:

WebClientLogin (no change)
ID = 900

WebClient (new row, inserted)
ID = 2, WebClientLogin_Id = 900

WebClient (original row, updated)
ID = 1, WebClientLogin_Id = 900 -> null  (error, rollback transaction)
...