【问题标题】:Convert List<X> to DBDataReader将 List<X> 转换为 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?乍一看,我看到它甚至提到了批量复制。

标签: c# entity-framework sqlbulkcopy dbdatareader


【解决方案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 作为主键。如果我取消注释该行,其他字段会受到影响吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-08
    • 2023-01-19
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多