wpf 比较两个数据表并在 LINQ 中显示另一个数据表中的差异

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27439614/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 12:47:06  来源:igfitidea点击:

Compare two DataTables and Display the differences in another datatable in LINQ

c#wpflinq

提问by Lakshminarayanan E

I have two DataTables and I want to display the rows. if both the datatables having the same value, Then mark X in all columns or else select the column with highest value(Eg:DT1: 10,DT2 :5)

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

Datatable1

数据表1

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

Datatable2

数据表2

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

I want the result to be:

我希望结果是:

Datatable3

数据表3

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

I have tried the below:-

我尝试了以下方法:-

 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;

Please help me on this. Thanks in advance

请帮我解决这个问题。提前致谢

回答by Rahul Singh

This is what I have:-

这就是我所拥有的:-

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>();

Since It is returning an anonymoustype, you can't use CopyToDataTablemethod, so please check thisto understand how I converted it into a datatable.

由于它返回一个anonymous类型,你不能使用CopyToDataTable方法,所以请检查这个以了解我如何将它转换为数据表。

I am getting this output:-

我得到这个输出:-

enter image description here

在此处输入图片说明

I have used following type for conversion purpose:-

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

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; }
 }

回答by Asif Iqbal

I have written in two query to achieve what you said..Perhaps you can optimize it further.

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

//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" + "-");
        }