【问题标题】:Reading in list using SqlDataReader C#使用 SqlDataReader C# 读取列表
【发布时间】:2016-10-12 20:41:02
【问题描述】:

我必须在while循环中填写一些列表:

while (_myReader_1.Read())
{
   _Row_Counter++;

   int _authorID = _myReader_1.GetInt32(0);
   Author _author = _eAthors.FirstOrDefault(_a => _a._AuthorID == _authorID);
   if (_author == null)
   {
      _author = new Author
      {
         _AuthorID = _authorID,
         _AuthorName = _myReader_1.GetString(1),
         _Attributes = new List<AuthorAttributes>()
      };  
   }  

   var _attribute = new AuthorAttributes()
   {
      _PaperID = new List<int>(),
      _CoAuthorID = new List<int>(),
      _VenueID = new List<int>()
   };

   _attribute._PaperID.Add(_myReader_1.GetInt32(2));
   _attribute._CoAuthorID.Add(_myReader_1.GetInt32(3));
   _attribute._VenueID.Add(_myReader_1.GetInt32(4));
   _attribute._Year = _myReader_1.GetInt32(5);

   _author._Attributes.Add(_attribute);

   _eAthors.Add(_author);

}
_myReader_1.Close();  

SQL表中的数据如下:

Author_ID | Author_Name | Paper_ID | CoAuthor_ID | Venue_ID | Year
------------------------------------------------------------------
677       | Nuno Vas    | 812229   | 901706      | 64309    | 2005  
677       | Nuno Vas    | 812486   | 901706      | 65182    | 2005  
677       | Nuno Vas    | 818273   | 901706      | 185787   | 2005  
677       | Nuno Vas    | 975105   | 901706      | 113930   | 2007  
677       | Nuno Vas    | 975105   | 1695352     | 113930   | 2007  
...       | ...         | ...      | ...         | ...      | ... 

问题是每次循环迭代时,都会创建新列表 _PaperID_CoAuthorID_VenueID,这是不需要的。因为我们有一个检查if(author == null),所以要创建一个新作者,同样我想检查一个作者是否存在_PaperID 的列表,例如对于Author_ID = 677,然后在同一列表中添加,直到Author_ID 被更改。

同样直到Author_ID = 677,列表_eAuthors 应该有Count = 1

我附上了一些图片来完善问题。

图片 1: 显示 eAuthors Count = 3,Attributes Count = 3,AuthorID = 677,而 3 次迭代通过,而 eAuthors Count 应该 = 1。

图片 2: 显示每行的单个属性列表,如第三次迭代中的属性,例如CoAuthorID,Count = 1,而在第 3 次迭代中它应该是 = 3,其余的 Attributes 也是一样的

【问题讨论】:

  • 这有严重的问题。你怎么知道 CoAuthor_ID 1695352 与哪篇论文相关联。或者当年份移到 2007 年时。您需要一个更正式的数据结构。
  • 我需要跟踪作者及其属性,即各自年份的论文、共同作者和地点,此处不需要 CoAuthor_ID 1695352 与哪篇论文相关
  • 嗯,你甚至没有得到各自的年。为什么新作者没有初始化这些列表?在我看来很草率。
  • 如果您只想了解作者发表的所有独特论文、合著者、地点和年份,而不考虑它们之间的关系,那么年份也应该在列表中。如果它们需要关联,那么您需要一个具有 PaperID、共同作者列表、交付它的地点 ID 和出版年份的类 Paper。然后,您将获得一份 Paper 项目列表。
  • @JohnD 你的观点很好,但是如果我们有一个Paper 作为一个类,你的回答代码会保持不变吗?我们仍然应该有每个作者的论文、共同作者和地点的列表......这个呢?

标签: c# list while-loop sqldatareader


【解决方案1】:

假设您的数据结构如下所示:

Author
    AuthorAttributes
        Papers (list)
            PaperID
        CoAuthors (list)
            CoAuthorID
        Venues (list)
            VenueID
        Year

你可以试试这个:

while (_myReader_1.Read())
{
    _Row_Counter++;

    int _authorID = _myReader_1.GetInt32(0);
    string _authorName = _myReader_1.GetString(1);
    int _paperID = _myReader_1.GetInt32(2);
    int _coAuthorID = _myReader_1.GetInt32(3);
    int _venueID = _myReader_1.GetInt32(4);
    int _year = _myReader_1.GetInt32(5);

    Author _author = _eAthors.FirstOrDefault(_a => _a._AuthorID == _authorID);
    if (_author == null)
    {
        _author = new Author
        {
             _AuthorID = _authorID,
             _AuthorName = _authorName,
             _AuthorAttributes = new AuthorAttributes
            {
                _Papers = new List<int>(),
                _Venues = new List<int>(),
                _Year = _year,
                _CoAuthors = new List<int>()
            }
        };  
        _eAthors.Add(_author); // only add if author not found
    }  

    if ( !_author._AuthorAttributes._Papers.Contains( _paperID ) )
        _author._AuthorAttributes._Papers.Add( _paperID );
    if ( !_author._AuthorAttributes._CoAuthors.Contains( _coAuthorID ) )
        _author._AuthorAttributes._CoAuthors.Add( _coAuthorID );
    if ( !_author._AuthorAttributes._Venues.Contains( _venueID ) )
        _author._AuthorAttributes._Venues.Add( _venueID );
}
_myReader_1.Close();  

【讨论】:

  • VenueID 也是列表,我这里没有Paper 类,而是有AuthorAttributes
  • 还有一件事! PaperID 也是一个列表,因为 Author_ID 有很多 Paper_ID
  • 如果我们不声明 List&lt;AuthorAttributes&gt; 而只声明为 AuthorAttributes 会怎样?因为AuthorAttributes 中的所有属性都是列表,除了Year
  • _author 被首先搜索。如果找到,它已经被创建并且已经定义了 _AuthorAttributes 并且 _AuthorAttributes 已经定义了它的列表。如果没有找到,则当场创建这些成员。无论哪种方式,它们都会存在。
  • if (!_author._AuthorAttributes._Papers.Contains( _paperID ), 名称_author在当前上下文中不存在名称_paperID在当前上下文中不存在 引发错误
【解决方案2】:

author == null 检查中初始化后立即添加新创建的作者。然后检查是否author.PaperID == null,如果是,添加AuthorAttributes。像这样:

while (_myReader_1.Read())
{
   _Row_Counter++;

   int _authorID = _myReader_1.GetInt32(0);
   Author _author = _eAthors.FirstOrDefault(_a => _a._AuthorID == _authorID);
   if (_author == null)
   {
      _author = new Author
      {
         _AuthorID = _authorID,
         _AuthorName = _myReader_1.GetString(1),
         _Attributes = new List<AuthorAttributes>()
      };  

      _eAthors.Add(_author); // ********** Add the new author
   }  

   // Watch out!!! author.Attributes may be null for existing authors!!!
   if (author.Attributes.PaperID == null || author.PaperID.Count == 0) // Check for PaperID existence
   {
       var _attribute = new AuthorAttributes()
       {
          _PaperID = new List<int>(),
          _CoAuthorID = new List<int>(),
          _VenueID = new List<int>()
       };

       _attribute._PaperID.Add(_myReader_1.GetInt32(2));
       _attribute._CoAuthorID.Add(_myReader_1.GetInt32(3));
       _attribute._VenueID.Add(_myReader_1.GetInt32(4));
       _attribute._Year = _myReader_1.GetInt32(5);

       _author._Attributes.Add(_attribute);
   }
}
_myReader_1.Close();  

当然,如果需要,您可以单独处理每个属性,为每个属性添加一个if 块。

【讨论】:

    【解决方案3】:

    按照显示的数据结构并查看图像中描绘的内容,似乎所有属性(Paper、CoAuthor、Venue)都是类型列表,因此无需将属性声明为List&lt;AuthorAttributes&gt;。按照这个来达到你想要的目标:

    while (_myReader_1.Read())
    {
       _Row_Counter++;
    
       int _authorID = _myReader_1.GetInt32(0);
       Author _author = _eAthors.FirstOrDefault(_a => _a._AuthorID == _authorID);
       if (_author == null)
       {
          _author = new Author
          {
             _AuthorID = _authorID,
             _AuthorName = _myReader_1.GetString(1),
             _Attributes = new AuthorAttributes()
          };
       }
    
       // Check if list _PaperID doesn't exist
       if (_author._Attributes._PaperID == null)
       {
          // Create new _PaperID
          _author._Attributes._PaperID = new List<int>();
          // Add Paper_ID to _PaperID
          _author._Attributes._PaperID.Add(_myReader_1.GetInt32(2));
       }
       else // Add Paper_ID to existing _PaperID list
       _author._Attributes._PaperID.Add(_myReader_1.GetInt32(2));
    
       // Check if list _CoAuthorID doesn't exist
       if (_author._Attributes._CoAuthorID == null)    
       {
          // Create new _CoAuthorID
          _author._Attributes._CoAuthorID = new List<int>();
          // Add CoAuthor_ID to _CoAuthorID
          _author._Attributes._CoAuthorID.Add(_myReader_1.GetInt32(3));
       }
       else // Add CoAuthor_ID to existing _CoAuthorID list
       _author._Attributes._CoAuthorID.Add(_myReader_1.GetInt32(3));
    
       // Check if list _CoAuthorID doesn't exist
       if (_author._Attributes._VenueID == null)    
       {
          // Create new _VenueID
          _author._Attributes._VenueID = new List<int>();
          // Add Venue_ID to _VenueID
          _author._Attributes._VenueID.Add(_myReader_1.GetInt32(4));
       }
       else // Add Venue_ID to existing _VenueID list
       _author._Attributes._VenueID.Add(_myReader_1.GetInt32(4));
    
       // Add Year to _Year
       _author._Attributes._Year =_myReader_1.GetInt32(5);
    
       if (!_eAthors.Contains(_author))
       _eAthors.Add(_author);
    }
    _myReader_1.Close();
    

    【讨论】:

    • 虽然每个属性分开处理,但看起来更漂亮!
    • 你不需要重复所有这些。添加。
    • 那么如何分别在每个属性列表中添加呢?
    • 呃 3 行,如果 (_author._Attributes._CoAuthorID == null) _author._Attributes._CoAuthorID = new List(); _author._Attributes._CoAuthorID.Add(_myReader_1.GetInt32(3));
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-11
    • 1970-01-01
    • 1970-01-01
    • 2011-08-02
    • 2020-02-24
    相关资源
    最近更新 更多