简体   繁体   English

如何在 C# 中多次将内容从一个数据表复制到另一个数据表

[英]How to Copy contents from one datatable to another datatable multiple times in C#

I want to copy the contents of Source table to the destination table based on the Id.我想根据 Id 将 Source 表的内容复制到目标表。 I want to copy the source table rows based on the Id.我想根据 Id 复制源表行。

Source Table:源表:

Src_Id  Name  age
------------------
0      Abc    20
1      Xyz    21

Destination Table:目的地表:

Des_Id     email       Country
--------------------------------
0     xyz@gmail.com   India   
0     abc@gmail.com   USA  
1     gag@gmail.com   Aus
1     ghu@gmail.com   Germany
1     tyu@gmail.com   India

Expected Result into Destination table目标表中的预期结果

Des_Id     email       Country    Src_Id  Name  age
------------------------------------------------------
0     xyz@gmail.com   India        0      Abc    20
0     abc@gmail.com   USA          0      Abc    20
1     gag@gmail.com   Aus          1      Xyz    21
1     ghu@gmail.com   Germany      1      Xyz    21
1     tyu@gmail.com   India        1      Xyz    21

I hope its help you more.我希望它对你有更多帮助。

    DataTable dt1 = new DataTable();
    dt1.Columns.Add("Src_Id",typeof(int));
    dt1.Columns.Add("Name",typeof(string));
    dt1.Columns.Add("age", typeof(int));

    dt1.Rows.Add(0,"Abc",20);
    dt1.Rows.Add(1, "Xyz", 21);

    DataTable dt2 = new DataTable();
    dt2.Columns.Add("Des_Id",typeof(int));
    dt2.Columns.Add("email",typeof(string));
    dt2.Columns.Add("Country", typeof(string));
             
    dt2.Rows.Add(0,"xyz@gmail.com","India");   
    dt2.Rows.Add(0,"abc@gmail.com","USA");  
    dt2.Rows.Add(1,"gag@gmail.com","Aus");
    dt2.Rows.Add(1,"ghu@gmail.com","Germany");
    dt2.Rows.Add(1, "tyu@gmail.com", "India");

    DataTable dtDestination = new DataTable();
    dtDestination.Columns.Add("Des_Id", typeof(int));
    dtDestination.Columns.Add("email", typeof(string));
    dtDestination.Columns.Add("Country", typeof(string));
    dtDestination.Columns.Add("Src_Id", typeof(int));
    dtDestination.Columns.Add("Name", typeof(string));
    dtDestination.Columns.Add("age", typeof(int));


    var results = from table1 in dt1.AsEnumerable()
                  join table2 in dt2.AsEnumerable() on (int)table1["Src_Id"] equals (int)table2["Des_Id"]
                  select new
                  {
                      Des_Id = (int)table2["Des_Id"],
                      email = (string)table2["email"],
                      Country = (string)table2["Country"],
                      Src_Id = (int)table1["Src_Id"],
                      Name = (string)table1["Name"],
                      age = (int)table1["age"]
                  };

    foreach (var item in results)
    {
        dtDestination.Rows.Add(item.Des_Id,item.email,item.Country,item.Src_Id,item.Name,item.age);
    }

I'd ensure the src_id is a primary key so the Find method will work:我会确保 src_id 是主键,因此 Find 方法将起作用:

src.PrimaryKey = new[]{ src.Columns["src_id"] };

Then create columns in dest and set values with loops:然后在 dest 中创建列并使用循环设置值:

foreach(DataColumn dc in src.Columns)
  dest.Columns.Add(dc.ColumnName, dc.DataType);

foreach(DataRow dr in dest.Rows){
  var x = src.Rows.Find(dr["dest_id"]);
  foreach(DataColumn dc in src.Columns)
    ro[dc.ColumnName] = x[dc.ColumnName];
}

Note: There isn't any error handling (such as source ID not found, dest table already contains a column called x etc) here but it's easy to add.注意:这里没有任何错误处理(例如找不到源 ID,目标表已经包含名为 x 的列等),但很容易添加。 The basic premise is that we add all the columns in src, to dest, then for every row in dest, look up for that row in source and use a loop on source's column names to copy the values across.基本前提是我们将 src 中的所有列添加到 dest,然后对于 dest 中的每一行,在 source 中查找该行,并在 source 的列名上使用循环来复制值。 If you do have a case where the column names are the same but the values differ the simplest solution might be to just change the name of the column in src until they are no longer the same (add an increment number) in the first loop, so the looping logic will still work (both tables need to have columns names the same for the second loop to work).如果您确实遇到列名相同但值不同的情况,最简单的解决方案可能是仅更改 src 中的列名,直到它们在第一个循环中不再相同(添加增量编号),所以循环逻辑仍然有效(两个表的列名需要相同才能使第二个循环工作)。 If you instead wish to pursue a positional route, and have the column names in dest differ from src (eg in src it's ColumnX but in dest it's ColumnX1) then you can easily loop the columns by numeral index:如果您希望采用定位路线,并且 dest 中的列名与 src 不同(例如,在 src 中是 ColumnX,但在 dest 中是 ColumnX1),那么您可以通过数字索引轻松循环列:

  for(int i = 0; i < x.ItemArray.Length; i++)
    ro[(dest.Columns.Count - src.Columns.Count) + i] = x[i];

After the operation, the dest table ends up being the datatable you wanted.操作后,dest 表最终成为您想要的数据表。 If you want a new datatable, leaving dest unmodified, you can clone dest first - I usually find it a wasted step when I do this kind of thing though如果你想要一个新的数据表,让 dest 保持不变,你可以先克隆 dest - 虽然我做这种事情时通常会发现这是一个浪费的步骤

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM