将 List<X> 转换为 DBDataReader

Posted

技术标签:

【中文标题】将 List<X> 转换为 DBDataReader【英文标题】:Convert List<X> to DBDataReader 【发布时间】:2019-09-17 07:25:21 【问题描述】:

如何将List&lt;Person&gt; personList 转换为DBDataReader

在下面给出的代码中,我尝试批量插入personList。我有大约 500k 条记录,WriteToServer 方法需要一个 DBDataReader,而我有一个 List&lt;Person&gt;。如何将List&lt;Person&gt; 转换为DBDataReader

using (SqlBulkCopy bc= new SqlBulkCopy(constr)) 
      bc.DestinationTableName = "MyPersonTable";
       try
       
             bc.WriteToServer(personList);
       
       catch (Exception ex)
       
             Console.WriteLine(ex.Message);
       
\

\

**Person Model**

public int personId get;set; // Primarykey
public string personName get;set; 
public int personAge get;set; 
public DateTime personCreatedDate get;set; 

【问题讨论】:

可能是this?乍一看,我看到它甚至提到了批量复制。 【参考方案1】:

您可以使用这个,然后使用 SqlBulkCopy 将所有数据插入数据库:

 IList<Name> list = new List<Name>();
    list.Add(new Name Forename="Bert", Surname="Fred");

    list.Add(new Name  Forename = "John", Surname = "Smith" );
    DataTable table = new DataTable();
    table.Columns.Add("Forename");
    table.Columns.Add("Surname");

    foreach (Name item in list)
    
        var row = table.NewRow();

        row["Forename"] = item.Forename;
        row["Surname"] = item.Surname;

        table.Rows.Add(row);
    

【讨论】:

【参考方案2】:

这是创建表格的通用方法。

还有另一种方法可以做到这一点,即创建一个继承自 IDataReader 的自定义类,如果您对此感兴趣,请随时告知。

不管怎样,看看下面,这是一种方法。

public static DataTable MakeTable(this List<object> o)

  var data = new DataTable();
  var props = o.FirstOrDefault()?.GetType().GetProperties();
  if (props == null)
      return data;
  forEach(var p in props)
        DataColumn c = new DataColumn();
        c.DataType = p.PropertyType;
        c.ColumnName = p.Name;
        // c.AutoIncrement = true; // if this is a primaryKey 
        data.Columns.Add(c);
  

  forEach(var item in o)
    var row = data.NewRow();
    forEach(var p in props)
     row[p.Name] = p.GetValue(item);
     
     data.Rows.Add(row);
  
  return data;

   // now all you need is to call MakeTable
   using (SqlBulkCopy bc= new SqlBulkCopy(constr)) 
      bc.DestinationTableName = "MyPersonTable";
       try
       
             bc.WriteToServer(personList.MakeTable());
       
       catch (Exception ex)
       
             Console.WriteLine(ex.Message);
       

【讨论】:

我只是将这个方法粘贴到我的类中,并删除了 static 关键字。我收到以下错误Severity Code Description Project File Line Suppression State Error CS1106 Extension method must be defined in a non-generic static class 是的,正如它所说,从参数中删除this :) 我已经用 Person 模型更新了我的帖子。我不明白如何为 Person 模型添加 DataType 和 ColumnName。请帮帮我。 什么意思,DataType 和 ColumnName 已经添加了。如果 propertyName 和 DataTable 与 db 中的 DataTable 相同,它应该可以工作。看看c.ColumnName = p.PropertyName;这行我指定columnName的地方 自动增量部分是如何工作的?我这里只有personId 作为主键。如果我取消注释该行,其他字段会受到影响吗?

以上是关于将 List<X> 转换为 DBDataReader的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Mono<List<String>> 转换为 Flux<String>

如何将DataTable转换成List<T>

将 List<List<Integer>> 转换为 int[][]

如何将 List<string> 转换为 List<myEnumType>?

如何将 List<Object> 转换为 List<MyClass>

如何在 Java Stream 中将 POJO 的列表转换为 Map<String,List>?