DataSet вызывает NoNullAllowedException, даже если передано значение! - PullRequest
0 голосов
/ 25 сентября 2010

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

code
        var newRow = _db.Messages.NewMessagesRow(); // _db is a strong-typed-dataset
        {
            newRow.Title = title;
            newRow.Text = text;
            newRow.ReceiverUID = receiverUID;
            newRow.Deleted = false;
        }

        // I lock the _db.Messages, so it happens one at a time
        lock ( _db.Messages ) 
        {
            _db.Messages.AddMessagesRow( newRow );
            _adapterMessages.Connection.Open();
            _adapterMessages.Update( newRow );
            newRow.MessageID = (Int64)_adapterMessages.GetIdentity();
            newRow.AcceptChanges();
            _adapterMessages.Connection.Close();
        }

NewMessagesRow () и AddMessagesRow () автоматически генерируются VS.Я сделал это, добавив элемент DataSet (файл .xsd) и перетащив в него все таблицы БД.

        public MessagesRow NewMessagesRow() {
            return ((MessagesRow)(this.NewRow()));
        }
        public void AddMessagesRow(MessagesRow row) {
            this.Rows.Add(row);
        }

_db - это DataSet (строго типизированный, автоматически сгенерированный VS). _Db.DataTable.

во время тестирования я получаю

System.Data.NoNullAllowedException: Column 'Deleted' does not allow nulls.
   at System.Data.DataColumn.CheckNullable(DataRow row)
   at System.Data.DataTable.RaiseRowChanging(...)
   at System.Data.DataTable.SetNewRecordWorker(...)
   at System.Data.DataTable.InsertRow(...)
   at System.Data.DataRowCollection.Add(DataRow row)
   at Server.Database.MessagesDataTable.AddMessagesRow(MessagesRow row)

AddMessagesRow () вызывается только в коде выше, и я всегда устанавливаю false для столбца Deleted, но все равно получаю это сообщение...

Я нигде не использую _adapterMessages, но есть и другие адаптеры (_adapterUsers, _adapterMatches и т. Д.), Которые могут использоваться одновременно.исключение каждый раз, но если сервер работает в течение некоторого времени (например,> 30 минут) с примерно 1000 одновременных игроков, это происходит.

Любая помощь или советы будут высоко оценены.Спасибо:)

1 Ответ

0 голосов
/ 08 октября 2010

Я выяснил причину этой проблемы. Я думал, DataTable.NewRow () был потокобезопасным, но это не так. Я должен блокировать только перед вызовом NewRow () для любых таблиц.

поэтому приведенный выше код необходимо изменить следующим образом:

    lock ( _db.Messages )
    {
        var newRow = _db.Messages.NewMessagesRow();
        {
            newRow.Title = title;
            newRow.Text = text;
            newRow.ReceiverUID = receiverUID;
            newRow.Deleted = false;
        }

        _db.Messages.AddMessagesRow( newRow );
        _adapterMessages.Connection.Open();
        _adapterMessages.Update( newRow );
        newRow.MessageID = (Int64)_adapterMessages.GetIdentity();
        newRow.AcceptChanges();
        _adapterMessages.Connection.Close();
    }

Вы можете обратиться к результатам поиска Google по этому вопросу.

...