【问题标题】:Comparing two column List<> based on column one根据第一列比较两列 List<>
【发布时间】:2017-11-21 21:05:24
【问题描述】:

我正在尝试使用 C# 比较两个 SQL 数据库。 我将第一个数据库中的字段列表存储在一个两列列表中。 我将如何将一个列表中的两列匹配到另一列?两个数据库都输出具有完全相同以下两列(CustNo、CustName)的列表。

CustNo 是主键,所以我想遍历所有 CustNo 字段并查找 CustName 是否已更改。

using static ESLBlackBox.MasterReport;

class Program
{
    static void Main(string[] args)
    {
        Program program = new Program();

        var changed = program.ReadNewMasterReport()
            .Where(b => program.ReadOldMasterReport()
            .Any(a => a.custNo == b.custNo && a.custName != b.custName))
            .ToList();

        Console.WriteLine(changed);
    }

    public List<Fields> ReadOldMasterReport()
    {
        SqlDataReader rdr = null;
        SqlConnection conn = new SqlConnection("Data Source=ESLAXSQLDEV1;Initial Catalog=ESLBlackBox;Integrated Security=True");
        SqlCommand cmd = new SqlCommand("select * from Master_Report", conn);
        List<Fields> oldResult = new List<Fields>();

        try
        {
            using (conn)
            {
                conn.Open();
                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    while (reader != null && reader.Read())
                    {
                        oldResult.Add(new Fields
                        {
                            custNo = Convert.ToString(reader["Service Address Cust No"]),
                            custName = Convert.ToString(reader["Service Address Acct Name"])
                        });
                    }
                }
            }
        }
        finally
        {
            if (rdr != null)
            {
                rdr.Close();
            }

            if (conn != null)
            {
                conn.Close();
            }
        }
        return oldResult;
    }

MasterReport 类

class MasterReport
{
    public class Fields
    {
        public string custNo { get; set; }
        public string custName { get; set; }
    }
}

【问题讨论】:

  • 你想在 DB 中还是在内存中这样做?
  • 可能在内存中。什么会更快?我们可能会迭代超过 100,000 行。
  • 你错了!您的类(字段)有两个属性,因此它代表表中的一行。在您的循环中,您应该将两列分配到您正在创建的新对象的同一个实例中。
  • 如果这两个数据库在同一台服务器上,那么您可以使用跨数据库连接进行比较。这比在内存中这样做要快得多
  • @Steve 是的,数据库在同一台服务器上。

标签: c# sql list sqldatareader


【解决方案1】:

您可以为此使用 linq:

var changed = listB
    .Where(b => listA
        .Any(a => a.custNo == b.custNo && a.custName != b.custName))
    .ToList();

【讨论】:

  • 谢谢。我试过这个,但是,当它执行这段代码时似乎什么都没有发生。是否可能需要很长时间才能进行比较?目前每个数据库表中只有 600 条记录。更新了上面的代码以显示它是如何被调用的,以防我做错了。
  • 改变的是一个列表。相反,Console.Writeline(changed.Count) 或类似的东西。
  • 它永远不会到达 Console.WriteLine(changed.Count) 行,因为它停留在上面的 linq 代码上。
  • 我不会将 program.ReadMasterReport() 和另一个放在 linq 调用内部,而是用它们制作实际的对象并使用它们。我想说它并没有挂在 linq 本身 - 尤其不是只有 600 行,但它可能会挂在你的 sql 中的某个地方。
  • 谢谢,@Brandon Miller,你是对的。当它返回下一个数据库时,数据正在擦除其中一个返回值。用对象修复,Linq 代码运行良好。
【解决方案2】:

由于两个数据库位于同一台服务器上,因此您可以进行跨数据库连接以找出差异。

SELECT tb1.CustNo, tb1.CustName, tb2.CustName FROM db1.dbo.Master_Report tb1 INNER JOIN db2.dbo.Master_Report tb2 ON tb1.CustNo = tb2.CustNo WHERE tb1.CustName != tb2.CustName;

这样您就可以避免加载数十万个条目并在内存中进行比较。数据库会为您完成繁琐的工作。

【讨论】:

    猜你喜欢
    • 2018-08-26
    • 1970-01-01
    • 1970-01-01
    • 2015-04-27
    • 1970-01-01
    • 2021-01-28
    • 1970-01-01
    • 1970-01-01
    • 2018-10-07
    相关资源
    最近更新 更多