【问题标题】:Compare two DataTables and Display the differences in another datatable in LINQ比较两个数据表并在 LINQ 中显示另一个数据表中的差异
【发布时间】:2014-12-12 21:17:55
【问题描述】:

我有两个数据表,我想显示行。如果两个数据表具有相同的值,则在所有列中标记X,否则选择具有最高值的列(例如:DT1:10,DT2:5)

数据表1

id       Name      Weight
1        Ship       500
2        Train      600
3        Plane      700
4        Car        800

数据表2

  id  Name       Weight
  1    Ship      500
  3    Plane     600
  4    Car       200

我希望结果是:

数据表3

id    Name      Weight          Datatable1        Datatable2
  1   Ship      500              X                 X
  2   Train     600              X
  3   Plane     700              X                 X
  4   Car       800              X

我尝试了以下方法:-

 DataTable Datatable3 = (from a in Datatable1.AsEnumerable() 
                         join b in Datatable2.AsEnumerable() 
                         on a["Name"].ToString() equals b["Name"].ToString()
                         a["Weight"].ToString() equals b["Weight"].ToString() into g 
                         where g.Count() != 1 select a).CopyToDataTable();
 dataGrid1.ItemsSource = Datatable3.DefaultView;

请帮助我。提前致谢

【问题讨论】:

  • 你尝试了什么?
  • 感谢您的帮助。我试过下面的 DataTable Datatable3 = (from a in Datatable1.AsEnumerable() join b in Datatable2.AsEnumerable() on a["Name"].ToString() equals b["Name"].ToString() a[" Weight"].ToString() 等于 b["Weight"].ToString() 到 g 其中 g.Count() != 1 选择 a).CopyToDataTable(); dataGrid1.ItemsSource = Datatable3.DefaultView;
  • 您可以改为编辑问题并包含您的代码。
  • 您有机会查看我的答案吗?让我知道这是否是您所期望的。一个快速查询,我认为在上面的 DataTable3 中,列 Datatable2 不应该有 id 3 的 X 对吗?自 700 != 600 :)
  • 我到现在还没有得到输出,仍然发现一些问题。但在这种情况下,我们需要用(X) 向各个数据表(即700)显示最大大小。带有“X”表示平面的 Datatable1。

标签: c# wpf linq


【解决方案1】:

这就是我所拥有的:-

DataTable Datatable3 = dt1.AsEnumerable().Union(dt2.AsEnumerable())
         .GroupBy(x => x.Field<int>("Id"))
         .Select(x =>
             {
                 var topWeightItem = x.OrderByDescending(z => z.Field<int>  ("Weight")).First();
                  return new Items
                  {
                     Id = x.Key,
                     Name = topWeightItem.Field<string>("Name"),
                     Weight = topWeightItem.Field<int>("Weight"),
                     DataTable1 = dt1.AsEnumerable().Any(z => z.Field<int>("Id") == x.Key 
                                  && z.Field<int>("Weight") == topWeightItem.Field<int>("Weight")
                                  && z.Field<string>("Name") == topWeightItem.Field<string>("Name")) 
                                  ? "X" : String.Empty,
                     DataTable2 = dt2.AsEnumerable().Any(z => z.Field<int>("Id") == x.Key 
                                  && z.Field<int>("Weight") == topWeightItem.Field<int>("Weight") 
                                  && z.Field<string>("Name") == topWeightItem.Field<string>("Name")) 
                                  ? "X" : String.Empty
                    };
               }
         ).PropertiesToDataTable<Items>();

由于它返回的是anonymous类型,所以不能使用CopyToDataTable方法,所以请查看this了解我是如何将其转换为数据表的。

我得到这个输出:-

我使用以下类型进行转换:-

public class Items
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Weight { get; set; }
    public string DataTable1 { get; set; }
    public string DataTable2 { get; set; }
 }

【讨论】:

  • 谢谢。但是当我试图整合时。我遇到了“TypeDescriptor”的问题。就像“名称 TypeDescriptor 在当前上下文中不存在。
  • @LakshminarayananE - 请包含 using System.ComponentModel; 命名空间。
  • 现在在此类中显示错误“必须在非泛型静态类中定义扩展方法”。公共部分类 MainWindow : Window {
  • @lakshminarayanana- 请将该扩展方法包含在静态类中!
  • @RahulSingh,很好的解决方案。我认为帮助那些不想学习和一遍又一遍地问同样问题的人是不值得的(即使在其他编程论坛上,比如 CodeProject)。
【解决方案2】:

我已经写了两个查询来实现你所说的......也许你可以进一步优化它。

//datatable1
         DataTable dt1 = new DataTable();

        dt1.Columns.Add("Id");
        dt1.Columns.Add("Name");
        dt1.Columns.Add("Weight");

        DataRow dr ;

        dr = dt1.NewRow();
        dr["Id"] = 1;
        dr["Name"] = "Ship";
        dr["Weight"] = 500;
        dt1.Rows.Add(dr);


        dr = dt1.NewRow();
        dr["Id"] = 2;
        dr["Name"] = "Train";
        dr["Weight"] = 600;
        dt1.Rows.Add(dr);


        dr = dt1.NewRow();
        dr["Id"] = 3;
        dr["Name"] = "Plane";
        dr["Weight"] = 700;
        dt1.Rows.Add(dr);

        dr = dt1.NewRow();
        dr["Id"] = 4;
        dr["Name"] = "Car";
        dr["Weight"] = 400;
        dt1.Rows.Add(dr);

         //datatable2
        DataTable dt2 = new DataTable();
        dt2.Columns.Add("Id");
        dt2.Columns.Add("Name");
        dt2.Columns.Add("Weight");
        DataRow dr2;
        dr2 = dt2.NewRow();
        dr2["Id"] = 1;
        dr2["Name"] = "Ship";
        dr2["Weight"] = 500;
        dt2.Rows.Add(dr2);

        dr2 = dt2.NewRow();
        dr2["Id"] = 3;
        dr2["Name"] = "Plane";
        dr2["Weight"] = 700;
        dt2.Rows.Add(dr2);

        dr2 = dt2.NewRow();
        dr2["Id"] = 4;
        dr2["Name"] = "Car";
        dr2["Weight"] = 400;
        dt2.Rows.Add(dr2);

        //iterate through table1
        IEnumerable<DataRow> table1 = from r in dt1.AsEnumerable()
                                      select r;

        //iterate through table2
        IEnumerable<DataRow> table2 = from r in dt2.AsEnumerable()
                                      select r;

        Console.WriteLine("Id\tName\tWeight\tDatatable1\tDatatable2");
        Console.WriteLine("----------------------------------------------------");
        //prints the common records
        foreach (DataRow td1 in table1.Distinct())//Matches wholes of the Element Sequence inside IEnumerable
        {
            table2.Distinct().ToList().ForEach(td2 =>
            {
                if (td1.Field<string>("Id") == td2.Field<string>("Id"))
                {
                    Console.WriteLine(td1.Field<string>("Id") + "\t" + td1.Field<string>("Name") + "\t" + td1.Field<string>("Weight") + "\t" + "x" + "\t\t" + "x");
                }
            });
        }
        //prints the missing records
        var query = (from tb1 in dt1.AsEnumerable()
                     join tb2 in dt2.AsEnumerable()
                     on tb1.Field<string>("Id") equals tb2.Field<string>("Id") into subset
                     from sc in subset.DefaultIfEmpty()
                     where sc == null
                     select new
                     {
                         id = tb1.Field<string>("Id"),
                         name = tb1.Field<string>("Name"),
                         wt = tb1.Field<string>("Weight")
                     }).Distinct();

        foreach (var td1 in query)
        {
            Console.WriteLine(td1.id + "\t" + td1.name + "\t" + td1.wt + "\t" + "x" + "\t\t" + "-");
        }

【讨论】:

  • 谢谢,但它应该比较两个表,结果应该显示在两个表中。如果值在两个表中。 X 应该在两个表中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-28
相关资源
最近更新 更多