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# 数据表。比较列中的数据,如果匹配,则追加相应行另一列中的数据的主要内容,如果未能解决你的问题,请参考以下文章

如果 2 行在 2 列中有数据匹配,则排除数据行

在 Pandas 数据框中追加或添加行

如果同一行中另一列中的值匹配,如何比较列的两个值

匹配两列中的单元格值,如果匹配,则将另一个值复制到空白单元格

比较两列中的数据并相互匹配数字

比较 Excel 工作表列数据,然后将数据填充到下一个列(如果有匹配)