用 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 个步骤,因为 问题是如何在问题中呈现的:
- 从数据库
设置table的主键列
- 将文本文件中 table 中的匹配列命名为相同
- 致电
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
我必须从纯文本文件导入信息,使用三个字段将其与数据库记录匹配。
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 个步骤,因为 问题是如何在问题中呈现的:
- 从数据库 设置table的主键列
- 将文本文件中 table 中的匹配列命名为相同
- 致电
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 中使用 ASdtF.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