C# 数据表。比较列中的数据,如果匹配,则追加相应行另一列中的数据
Posted
技术标签:
【中文标题】C# 数据表。比较列中的数据,如果匹配,则追加相应行另一列中的数据【英文标题】:C# Datatable. Compare data from a column and if it matches, append the data from another column of the corresponding row 【发布时间】:2021-07-19 10:00:30 【问题描述】:例如, 如果我有以下数据表,
Location | First name | Pincode | Manager |
---|---|---|---|
Sydney | John | 123 | Brian |
New York | Larry | 456 | Sherry |
Chicago | Meg | 789 | Linda |
Dallas | Mark | 012 | Cooper |
Sydney | Jack | 123 | Brian |
Dallas | Chandler | 012 | Cooper |
Sydney | Richard | 123 | Brian |
在这里,要遍历的第一列是位置。只要 Location 匹配,遍历所有对应的 First Names 并将其保持在逗号分隔的单行中。
Location | First Name | Pincode | Manager |
---|---|---|---|
Sydney | John,Jack,Richard | 123 | Brian |
New York | Larry | 456 | Sherry |
Chicago | Meg | 789 | Linda |
Dallas | Mark,Chandler | 012 | Cooper |
我已将其存储在 Datatable 变量 dt 中,如下所示:
DataTable dt = new DataTable();
using (SqlConnection sqlConn = new SqlConnection(ConfigurationManager.AppSettings["connectionString"].ToString()))
sqlConn.Open();
using (SqlCommand cmd = new SqlCommand(script, sqlConn))
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
adapter.SelectCommand.CommandTimeout = 3 * 60;
adapter.Fill(dt);
【问题讨论】:
欢迎来到 ***!请与我们分享到目前为止您尝试了哪些方法以及您遇到的问题。 @PeterCsala 谢谢。我对 DataTable 操作不是很满意。这就是为什么我需要一个建议。我从 MS-SQL 数据库中提取了这些数据并将其添加到 Datatable 变量中。之后我想执行我要求的操作。 【参考方案1】:如果您没有 Datatable 格式的数据,代码会更简洁。
这样的事情应该可以解决你的问题
DataTable dt = new DataTable();
dt.Columns.Add("Location");
dt.Columns.Add("First_Name");
dt.Rows.Add("Sydney", "John");
dt.Rows.Add("New York", "Larry");
dt.Rows.Add("Chicago", "Meg");
dt.Rows.Add("Dallas", "Mark");
dt.Rows.Add("Sydney", "Jack");
dt.Rows.Add("Dallas", "Chandler");
dt.Rows.Add("Sydney", "Richard");
var result = dt
.AsEnumerable()
.GroupBy(x => x["Location"])
.Select(group => new
Location = group.Key.ToString(),
First_Name = string.Join(",", group.Select(x => x["First_Name"]))
);
更新
如果您想将匿名类型转换回数据表,可以查看Best Practice: Convert LINQ Query result to a DataTable without looping
话虽如此。我觉得如果你朝着这个方向前进,最好以不同的方式完成这项任务。也许编写一个存储过程来完成这项工作(1 db call vs 2)
如果您想在 C# 中执行此操作,我会将此解决方案的实现更改为类似的内容
DataTable dtResult = new DataTable();
dtResult.Columns.Add("Location");
dtResult.Columns.Add("First_Name");
DataTable dt = dtResult.Clone();
dt.Rows.Add("Sydney", "John");
dt.Rows.Add("New York", "Larry");
dt.Rows.Add("Chicago", "Meg");
dt.Rows.Add("Dallas", "Mark");
dt.Rows.Add("Sydney", "Jack");
dt.Rows.Add("Dallas", "Chandler");
dt.Rows.Add("Sydney", "Richard");
var result = dt.AsEnumerable().GroupBy(x => x["Location"])
.Select(group => dtResult.Rows.Add(group.Key.ToString(),string.Join(",", group.Select(x => x["First_Name"]))));
【讨论】:
有一件小事:尽管group
不是reserved keyword,但最好避免使用它,因为每当要将 lambda 表达式转换为查询/语句表达式时,它可能会引起混淆。
好的。我想再次将处理后的数据存储在数据表中。我们如何做到这一点? PS-数据表包含更多列。这只是一个简化的例子。假设给定位置的其他列的值相同。
更新了问题以便更好地理解用例。
我觉得你走错了方向。为什么不使用存储过程来完成这项工作? 2 db 调用 vs 1?
@Neil 这真的很有帮助。实际上我无法解释我的整个用例。此操作只是简化流程其他部分的一部分。我对此有一个要点,并能够成功实施它。非常感谢。【参考方案2】:
您需要使用 GroupBy Location 列并连接 First Name Column。
类似
_context.Locs.GroupBy(l => new l.Location )
.Select(g => new g.Key.Location , Names = string.Join(",", g.Select(i => i.FirstName)) );
看看this question
【讨论】:
请注意,这不是 Linq-To-Sql 或 Linq-To-Entities 问题。所以这仅适用于强类型数据集,而不适用于普通数据表。在这种情况下使用尼尔的答案以上是关于C# 数据表。比较列中的数据,如果匹配,则追加相应行另一列中的数据的主要内容,如果未能解决你的问题,请参考以下文章