即使传递了值,DataSet也会引发NoNullAllowedException!

时间:2010-09-25 13:17:28

标签: c# sql database dataset tableadapter

我正在编写许多玩家连接的游戏服务器。 我将数据库加载到DataSet(强类型)。 每次玩家登录时,我都会使用TableAdapter向Messages表添加一个新行。

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.Messages是一个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(),并且我总是为Deleted列设置false,但仍然会收到此消息...

我不在其他任何地方使用_adapterMessages,但还有其他可以同时使用的适配器(_adapterUsers,_adapterMatches,...等)。

我不是每次都得到例外,但是如果服务器运行一段时间(例如> 30分钟)并且有大约1000个并发玩家,那么它就会发生。

任何帮助或建议将不胜感激。 谢谢:))

1 个答案:

答案 0 :(得分:0)

我找出了这个问题的根本原因。 我认为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 search results ..