2010-09-25 41 views
0

我正在写一个游戏服务器,许多玩家连接到这个服务器。 我将数据库加载到DataSet中(强类型)。 每次玩家登录时,我都会使用TableAdapter向Messages表添加新行。即使通过值,DataSet也会引发NoNullAllowedException!

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是一个数据表。

而在测试中,我得到

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()被调用只能在上面的代码中,我总是设置删除列假,但仍然得到这条消息...

我不要在其他地方使用_adapterMessages,但也可以同时使用其他适配器(_adapterUsers,_adapterMatches,...等)。

每次我都没有得到异常,但是如果服务器运行一段时间(比如大于30分钟)有大约1000个并发播放器,它就会发生。

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

+0

为NewMessagesRow和AddMessagesRow,并_db.Messages – 2010-09-25 15:20:07

+0

我的定义PLS邮编发布了NewMessagesRow()和AddMessagesRow()的代码:) _db.Messages只是扩展了DataTable的System.Data.TypedTableBase 。简而言之,它们都是VS所支持的DataTable和DataSet ..etc来支持强类型。 – wooohoh 2010-09-26 14:06:16

回答

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对这个问题..

相关问题