【问题标题】:Left outer join to perform DataTable Comparison using Linq使用 Linq 执行数据表比较的左外连接
【发布时间】:2014-04-15 13:32:05
【问题描述】:

我正在尝试使用 LINQ 语句比较两个数据表

我的表的结构是这样的

EmpId -- FirstName -- LastName -- DOB

Emp 是唯一键(当然是整数),DOB 是日期,其余是字符串。

有两个数据表进来

源表和目标表

TargetTable 的记录数可能相同或更少。 FirstName、LastName 或 DOB 的某些值可能不同。

这是没有左外连接的查询,它可以工作但不获取其余的源记录。

    var matched = from dtSource in sourceTable.AsEnumerable()
                  join dtTarget in targetTable.AsEnumerable() on dtSource.Field<int>("empid") equals dtTarget.Field<int>("empid")

                  where dtSource.Field<string>("firstname") != dtTarget.Field<string>("firstname")
                  || dtSource.Field<string>("lastname") != dtTarget.Field<string>("lastname")
                  || dtSource.Field<DateTime>("dob") != dtTarget.Field<DateTime>("dob")
                  select dtSource;

我正在尝试进行左外连接,以便获得目标数据表中不存在的其余记录。

这就是我正在尝试的

    var join = from dtSource in source
               join dtTarget in target
                   on dtSource.Field<int>("EmpId") equals dtTarget.Field<int>("EmpId")
               into outer
               where
               dtSource.Field<string>("firstname") != dtTarget.Field<string>("firstname")
                  || dtSource.Field<string>("lastname") != dtTarget.Field<string>("lastname")
                  || dtSource.Field<DateTime>("dob") != dtTarget.Field<DateTime>("dob")

               from dtEmpSal in outer.DefaultIfEmpty()

               select new
               {
                   FirstName = dtSource.Field<string>("FirstName") == null ? "" : dtSource.Field<string>("FirstName"),
                   LastName = dtSource.Field<string>("LastName") == null ? "" : dtSource.Field<string>("LastName"),
                   DOB = dtSource.Field<DateTime>("dob") == null ? DateTime.Today : dtSource.Field<DateTime>("dob")
               };

当然,我做错了,因为我无法在 where 子句中访问 dtTarget,因此无法编译它。我做错了什么,不知道是什么。

编辑:

这就是我的源数据表的样子

这就是我的目标的样子

在我的情况下,结果集应该包括 empIds 为 1、6、7 等的 emp 记录。注 1 不同(姓氏),目标 DataTable 中包含 2,3,4,5。

截图显示我的烦恼:

https://www.dropbox.com/s/145ba6oa59fstdc/screencap.wmv

我发现很难调试这个:(

【问题讨论】:

    标签: c# linq linq-to-dataset


    【解决方案1】:

    这对我有帮助

    public static dynamic GetAllDifferences (DataTable sourceTable,DataTable targetTable)
            {
                var source = sourceTable.AsEnumerable();
                var target = targetTable.AsEnumerable();
    
                var noMatchInSource = from dtSource in source
                    join dtTarget in target on dtSource.Field<int>("empid") equals dtTarget.Field<int>("empid")
                    where dtSource.Field<string>("firstname").Equals(dtTarget.Field<string>("firstname"))
                          && dtSource.Field<string>("lastname").Equals(dtTarget.Field<string>("lastname"))
                          && dtSource.Field<DateTime>("dob").Equals(dtTarget.Field<DateTime>("dob"))
                    select dtSource;
    
                var result =
                            from sourceDataRow in sourceTable.AsEnumerable()
                            where !(from noMatchDataRow in noMatchInSource
                                    select noMatchDataRow.Field<int>("empid"))
                                   .Contains(sourceDataRow.Field<int>("empid"))
                            select sourceDataRow;
                                    return result;
            }
    

    【讨论】:

      猜你喜欢
      • 2013-09-15
      • 2018-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-09
      • 1970-01-01
      相关资源
      最近更新 更多