用 C# 和 LinQ 匹配两个数据集

Matching two data sets with C# and LinQ

我必须从纯文本文件导入信息,使用三个字段将其与数据库记录匹配。

DB fields
RowId, DF1, DF2, DF3, 

Text file fields
TF1,TF2,TF3,TF4

Matching
DF1 = TF1
DF2 = TF2
DF3 = TF3

Result
RowID, TF4 (Optional, F1,F2,F3)

由于我对 C# 和 LinQ 的经验有限,这被证明很麻烦。

我尝试将数据库 table 和文本文件分别加载到 DataTable 中,并将它们转换为 Enumerable() 以便与 LinQ 一起使用,但找不到构建 LinQ 的代码参考 正确。

var result = (from db in dtDB.AsEnumerable()
join txt in dtTxt.AsEnumerable() on <<MATCH INSTRUCTION>>
where << WHERE INSTRUCTION >>
select new {
           db.RowID,
//         F1,
//         F2,
//         F3,
           txt.TF4
}).asArray
 

问题是如何引用“Enumerable”中的每个字段并构造Match和Where指令。 我应该使用其他结构而不是 DataTables 吗? 任何有关如何解决此问题的指示都会有所帮助。

要直接回答有关使用 linq 将 DataTables 与复合键连接的问题,您需要使用别名:

var result = from db in dtDB.AsEnumerable()
             join txt in dtTxt.AsEnumerable()
             on new { id = db.Field<string>("ID"), f1 = db.Field<string>("DF1"), f2 = db.Field<string>("DF2") }
                equals new { id = txt.Field<string>("ID"), f1 = txt.Field<string>("TF1"), f2 = txt.Field<string>("TF2") }
             where db.Field<string>("ID") == "xxx"
             select new
             {
                 id = db.Field<string>("ID"),
                 //         F1,
                 //         F2,
                 //         F3,
                 tf4 = txt.Field<string>("TF4")
             };

最简单的方法是使用数据table 中内置的功能来解决此问题。这是一行代码完成的工作,但这里有 3 个步骤,因为 问题是如何在问题中呈现的:

  1. 从数据库
  2. 设置table的主键列
  3. 将文本文件中 table 中的匹配列命名为相同
  4. 致电dataTableFromDb.Merge(dataTableFromTextFile);

第 1 步:


//for example, imagine your DB has given you this:
var dtDb = new DataTable();
dtDb.Columns.Add("RowId");
dtDb.Columns.Add("DF1");
dtDb.Columns.Add("DF2");
dtDb.Columns.Add("DF3");
dtDb.Rows.Add("Rowid1", "A", "B", "C");
dtDb.Rows.Add("Rowid2", "D", "E", "F");

//and your text file has given you this:
var dtF = new DataTable();
dtF.Columns.Add("TF1");
dtF.Columns.Add("TF2");
dtF.Columns.Add("TF3");
dtF.Columns.Add("TF4");
dtF.Rows.Add("A", "B", "C", "4");

第 2 步:确保链接列的列名称在每个 table 中都相同(在此过程中尽早重命名它们以使您的生活更轻松,例如,在从文本文件中读取时命名它们,或者在从 db)

填充 dtdb 时在 SQL 中使用 AS
dtF.Columns["TF1"].ColumnName = "DF1";
dtF.Columns["TF2"].ColumnName = "DF2";
dtF.Columns["TF3"].ColumnName = "DF3";

确保目标table有一个主键

dtDb.PrimaryKey = new[] { dtDb.Columns["DF1"], dtDb.Columns["DF2"], dtDb.Columns["DF3"] };

将文件table合并到数据库table

dtDb.Merge(dtF);

实际上,生成数据库 table 的过程应该给它主键(所以第 1 步应该是不必要的),并且从文件生成 table 的过程应该等同于列名(因此第 2 步应该是不必要的)所以实际上您需要使用的唯一代码行来自第 3 步:

dtDb.Merge(dtF);

dtDb table 是合并后的结果 table;你可以在屏幕上显示它并将它保存回数据库 etcc

https://dotnetfiddle.net/Ia71IM